首页 > 其他分享 >记一次切面中读取请求体报错 Cannot call getReader()

记一次切面中读取请求体报错 Cannot call getReader()

时间:2024-11-16 11:30:56浏览次数:1  
标签:getReader 请求 FilterRegistrationBean ContentCachingRequestWrapper request Cannot 

问题

写了一个切面来处理被指定自定义注解标注的方法:

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class MyAnnoAspect {

    private final HttpServletRequest request;

    @Around("@annotation(myAnno)")
    public Object handleMyAnno(ProceedingJoinPoint joinPoint, MyAnno myAnno) throws Throwable {
        String body = ServletUtil.getBody(request);
        // ...
        // 继续执行原方法
        return joinPoint.proceed(args);
    }
}

其中使用ServletUtil.getBody(request)来读取请求体。

测试发现,当 Controller 方法使用@RequestBody标注方法参数时。切面中获取请求体会报错UT010004: Cannot call getReader(), getInputStream() already called。因为request.getReader()已经在@RequestBody的处理逻辑中调用过了,不能重复调用。

解决

ContentCachingRequestWrapper是 Spring 提供的一个请求包装器,可以缓存请求体。

可以在 Servlet 过滤器中使用ContentCachingRequestWrapper包装原有请求,使请求体可以被多次读取。

先新建过滤器使用ContentCachingRequestWrapper来包装请求:

public class CustomRequestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        filterChain.doFilter(wrappedRequest, response);
    }
}

然后注册过滤器:

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<CustomRequestFilter> customFilter() {
        FilterRegistrationBean<CustomRequestFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new CustomRequestFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

其中OncePerRequestFilter本身实现了javax.servlet.Filter接口,所以实际上还是基于 Servlet 过滤器机制。

FilterRegistrationBean是 Spring Boot 提供的一个组件,允许开发者以编程方式注册和配置过滤器。

标签:getReader,请求,FilterRegistrationBean,ContentCachingRequestWrapper,request,Cannot,
From: https://www.cnblogs.com/Higurashi-kagome/p/18549199

相关文章

  • 下载HuggingFace模型的方法以及报错解决
    方法新建文件夹,右键,opengitbashhere设置全局代理#设置全局代理gitconfig--globalhttps.proxyhttp://127.0.0.1:7890gitconfig--globalhttps.proxyhttps://127.0.0.1:7890gitconfig--globalhttp.proxysocks5://127.0.0.1:7890gitconfig--globalhttps.p......
  • 短视频开源源码,报错信息显示ID重复的解决方案
    短视频开源源码,报错信息显示ID重复的解决方案原因分析在最终添加的方法中,出现了重复ID的报错。对于为什么ID会重复,我思考了很久也没有想通。我沿着代码往上找到了saveList。intbatchSize=5000;if(CollUtil.isNotEmpty(saveList)){List<List<Map<String,Obj......
  • 报错:ORA-00603、ORA-01092、ORA-00704, ORA-00604, ORA-00904
    基本情况在做备份还原的时候,可能是第三方备份软件的配置的原因,使得我在测试服务器做恢复测试时,使用的备份集不是我的预期的备份集。我想恢复的是19c的数据库,而我实际恢复的是一个11g的数据库。我在恢复控制文件、数据文件和归档日志文件的时候都很顺利,recoverdatabase也成功,但......
  • SpringBoot 3.3.5 集成 mybatis-plus-boot-starter 3.4.2报错
    一、环境JDK:17SpringBoot:3.3.5Mybatis-Plus:3.4.2二、报错信息Considerthefollowing: Ifyouwantanembeddeddatabase(H2,HSQLorDerby),pleaseputitontheclasspath. Ifyouhavedatabasesettingstobeloadedfromaparticularprofileyoumayneed......
  • 如何解决执行crictl命令报错的问题
    输入crictlimages提示[root@k8s-node1~]#crictlimagesWARN[0000]imageconnectusingdefaultendpoints:[unix:///var/run/dockershim.sockunix:///run/containerd/containerd.sockunix:///run/crio/crio.sockunix:///var/run/cri-dockerd.sock].Asthedefaultsetti......
  • Windows系统日志报错:生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。T
    当我们检查Windows系统日志发现有一个报错:生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。TLS协议所定义的严重错误代码是10。WindowsSChannel错误状态是1203。导致报错的原因是什么?该如何处理?驰网飞飞和你分享其实这个报错和“生成以下严重警告:10。内部错误......
  • git拉取代码报错invalid path解决,以及windows的一个坑
    错误日志:Cloninginto'overmind-efficiency'...remote:Enumeratingobjects:702,done.remote:Countingobjects:100%(702/702),done.remote:Compressingobjects:100%(286/286),done.remote:Total126341(delta287),reused581(delta221),pack-reu......
  • <a-modal>打开页面报错Ancestor with aria-hidden
    报错信息Blockedaria-hiddenonanelementbecauseitsdescendantretainedfocus.Thefocusmustnotbehiddenfromassistivetechnologyusers.Avoidusingaria-hiddenonafocusedelementoritsancestor.Considerusingtheinertattributeinstead,whichwi......
  • thinkphp升级后报错Declaration of think\app\Url::build() must be compatible wit
    ​将源码中的thinkphp升级后,发现了错误:Declarationofthink\app\Url::build()mustbecompatiblewiththink\route\Url::build():string出现这个错误的原因是,你通过命令“composerupdatetopthink/framework”只升级了框架,没有更新多应用扩展模块。只需要composer运行下面......
  • 【ARM】MDK语言标准执行报错Error:268
    【更多软件使用问题请点击亿道电子官方网站】1、问题场景客户在编译的过程中,MDK出现下列报错Error:#268:declarationmaynotappearafterexecutablestatementinblock。记录解决步骤和其他解决思路进行记录,后续该报错信息出现,使用文档快速解决客户问题。问题分析......