从Spring异常处理程序中读取httprequest内容

从Spring异常处理程序中读取httprequest内容,第1张

从Spring异常处理程序中读取httprequest内容

当您从中读取内容时,我已经尝试过您的代码,并且在异常处理程序中发现了一些错误

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
注释收到请求主体时,也可以在该控制器中复制该请求主体。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5676011.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存