解决异常处理问题:getReader() has already been called for this

 更新时间:2024年01月30日 08:33:00   作者: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);
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis模糊查询like语句该如何写

    mybatis模糊查询like语句该如何写

    MyBatis模糊查询通常使用LIKE关键字,结合concat函数拼接通配符%实现,在MyBatis配置文件中,通过#{keyword}传递参数,生成带有通配符的查询语句,MyBatis-Plus中,通过LambdaQueryWrapper类和like方法构建模糊查询条件,简化查询操作
    2024-09-09
  • Java中Arrays数组工具类的基本使用详解

    Java中Arrays数组工具类的基本使用详解

    Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而"不用"使用对象来调用(注意:是"不用" 而不是 "不能"),这篇文章主要给大家介绍了关于Java中Arrays数组工具类的基本使用,需要的朋友可以参考下
    2021-12-12
  • JVM的垃圾回收机制真是通俗易懂

    JVM的垃圾回收机制真是通俗易懂

    这篇文章主要为大家详细介绍了JVM的垃圾回收机制,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 解决@PathVariable对于特殊字符截断的问题

    解决@PathVariable对于特殊字符截断的问题

    这篇文章主要介绍了解决@PathVariable对于特殊字符截断的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java中try-catch-finally执行顺序你知道吗

    Java中try-catch-finally执行顺序你知道吗

    本文主要介绍了try-catch-finally执行顺序你知道吗,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • SpringBoot整合Jasypt实现配置文件和数据库字段敏感数据的加解密

    SpringBoot整合Jasypt实现配置文件和数据库字段敏感数据的加解密

    很多时候为了保证数据的安全,在处理敏感数据、前后端数据传输、数据库敏感数据入库等,数据的加密和解密是不可忽视的重要环节,下面我们就来看看如何在SpringBoot整合Jasypt实现配置文件和数据库字段敏感数据的加解密吧
    2025-09-09
  • Servlet开发JavaWeb工程示例详解

    Servlet开发JavaWeb工程示例详解

    这篇文章主要介绍了Servlet开发JavaWeb工程示例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • SpringMVC配置多个properties文件之通配符解析

    SpringMVC配置多个properties文件之通配符解析

    这篇文章主要介绍了SpringMVC配置多个properties文件之通配符解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • MySql多表查询 事务及DCL

    MySql多表查询 事务及DCL

    这篇文章主要介绍了MySql多表查询 、事务、DCL的相关资料,需要的朋友可以参考下面文章内容
    2021-09-09
  • IDEA更改Terminal的方法步骤

    IDEA更改Terminal的方法步骤

    Windows上开发有时候cmd不支持bash命令,有些操作就会非常麻烦,本文主要介绍了IDEA更改Terminal的方法步骤,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09

最新评论