解决异常处理问题:getReader() has already been called for this
作者:magic_kid_2010
这篇文章主要介绍了解决异常处理:getReader() has already been called for this问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
场景描述
在 Spring Boot 自定义拦截器中,需要对请求 body 中的内容做签名验证。
在日志切面中,需要打印请求 body 中的内容。
报错内容
java.lang.IllegalStateException: getReader() has already been called for this request
at org.apache.catalina.connector.Request.getInputStream(Request.java:1069)
at org.apache.catalina.connector.RequestFacade.getInputStream(RequestFacade.java:365)
at com.igg.aggregate.server.aspect.LogAspect.before(LogAspect.java:80)
原因分析
HttpServletRequest 的 getInputStream() 和 getReader() 都只能读取一次,由于 Request Body 是流的形式读取,那么
流读了一次就没有了,所以只能被调用一次。
解决办法
先将 Request Body 保存,然后通过 Servlet 自带的 HttpServletRequestWrapper 类覆盖 getReader() 和
getInputStream() 方法,使流从保存的body读取。
然后再Filter中将ServletRequest替换为AuthenticationRequestWrapper。
代码示例:
public class MyRequestWrapper extends HttpServletRequestWrapper { private byte[] body; public MyRequestWrapper(HttpServletRequest request) throws IOException { super(request); StringBuilder sb = new StringBuilder(); String line; BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) { sb.append(line); } String body = sb.toString(); this.body = body.getBytes(StandardCharsets.UTF_8); } public String getBody() { return new String(body, StandardCharsets.UTF_8); } }
// 获取请求body try { MyRequestWrapper myRequestWrapper = new MyRequestWrapper(request); return myRequestWrapper.getBody(); } catch (IOException e) { log.error("get request body exception", e); throw new RuntimeException(e); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 解决java启动时报线程占用报错:Exception in thread “Thread-14“ java.net.BindException: Address already in use: bind
- 如何解决Mybatis--java.lang.IllegalArgumentException: Result Maps collection already contains value for X
- SVN出现提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir解决方案
- 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
- 如何解决getReader() has already been called for this request问题