当您从中读取内容时,我已经尝试过您的代码,并且在异常处理程序中发现了一些错误
InputStream:
Writer writer = new StringWriter();byte[] buffer = new byte[1024];//Reader reader2 = new BufferedReader(new InputStreamReader(request.getInputStream()));InputStream reader = request.getInputStream();int n;while ((n = reader.read(buffer)) != -1) { writer.toString();}String retval = writer.toString();retval = "";
我已经用以下代码替换了您的代码:
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));String line = "";StringBuilder stringBuilder = new StringBuilder();while ( (line=reader.readLine()) != null ) { stringBuilder.append(line).append("n");}String retval = stringBuilder.toString();
然后,我可以从
InputStream异常处理程序中读取内容,它可以正常工作!如果仍然无法读取
InputStream,建议您检查如何将xml数据发布到请求正文。您应该考虑
Inputstream每个请求只能使用一次,因此建议您检查是否没有其他对的调用
getInputStream()。如果必须调用它两次或更多次,则应编写一个
HttpServletRequestWrapper这样的自定义内容来制作请求正文的副本,以便可以多次阅读。
更新
您的评论已帮助我重现此问题。您使用了@RequestBody注释,因此您没有调用
getInputStream(),但是Spring会调用它来检索请求的正文。看一看该类
org.springframework.web.bind.annotation.support.HandlerMethodInvoker:如果使用
@RequestBody此类调用
resolveRequestBody方法,依此类推…最终您将无法再
InputStream从中读取
ServletRequest。如果仍然要同时使用
@RequestBody和
getInputStream()自己的方法,则必须将请求包装到自定义文件中
HttpServletRequestWrapper以制作请求正文的副本,以便可以手动读取多次。这是我的包装:
public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper { private static final Logger logger = Logger.getLogger(CustomHttpServletRequestWrapper.class); private final String body; public CustomHttpServletRequestWrapper(HttpServletRequest request) { super(request); StringBuilder stringBuilder = new StringBuilder(); BufferedReader bufferedReader = null; try { InputStream inputStream = request.getInputStream(); if (inputStream != null) { bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line = ""; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line).append("n"); } } else { stringBuilder.append(""); } } catch (IOException ex) { logger.error("Error reading the request body..."); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ex) { logger.error("Error closing bufferedReader..."); } } } body = stringBuilder.toString(); } @Override public ServletInputStream getInputStream() throws IOException { final StringReader reader = new StringReader(body); ServletInputStream inputStream = new ServletInputStream() { public int read() throws IOException { return reader.read(); } }; return inputStream; }}
然后,您应该编写一个简单
Filter的包装请求:
public class MyFilter implements Filter { public void init(FilterConfig fc) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(new CustomHttpServletRequestWrapper((HttpServletRequest)request), response); } public void destroy() { }}
最后,您必须在web.xml中配置过滤器:
<filter> <filter-name>MyFilter</filter-name> <filter-class>test.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
您可以仅针对确实需要过滤器的控制器触发过滤器,因此应根据需要更改url-pattern。
如果仅在一个控制器中需要此功能,当您通过
@RequestBody注释收到请求主体时,也可以在该控制器中复制该请求主体。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)