SpringBoot拦截器获取RequestBody的巨坑

在SpringBoot开发中,拦截器(Interceptor)是常用的功能组件,但很多开发者在使用拦截器获取RequestBody时会遇到各种"坑"。本文将揭示这些常见问题及解决方案。

问题根源

拦截器获取RequestBody的主要问题在于:HttpServletRequest的输入流只能读取一次。当请求体被Controller或其他组件读取后,输入流就会关闭,导致拦截器中再次读取时抛出异常。

常见场景

1.直接读取导致后续处理失败:在拦截器中调用`request.getInputStream()`后,Controller中`@RequestBody`注解会失效
2.包装类使用不当:虽然可以通过`ContentCachingRequestWrapper`缓存请求体,但需要在Filter层就进行包装
3.性能问题:缓存大请求体会显著增加内存消耗

解决方案

1.使用Filter提前包装请求:
```java
publicclassRequestWrapperFilterextendsOncePerRequestFilter{
@Override
protectedvoiddoFilterInternal(HttpServletRequestrequest,
HttpServletResponseresponse,
FilterChainfilterChain){
ContentCachingRequestWrapperwrappedRequest=newContentCachingRequestWrapper(request);
filterChain.doFilter(wrappedRequest,response);
}
}
```

2.在拦截器中安全读取:
```java
@Override
publicbooleanpreHandle(HttpServletRequestrequest,
HttpServletResponseresponse,
Objecthandler){
if(requestinstanceofContentCachingRequestWrapper){
ContentCachingRequestWrapperwrapper=(ContentCachingRequestWrapper)request;
byte[]body=wrapper.getContentAsByteArray();
//处理body内容
}
returntrue;
}
```

最佳实践

1.仅在实际需要时读取请求体
2.对大请求体考虑流式处理
3.在拦截器中避免修改请求体内容
4.注意字符编码问题

理解这些"坑"并采用正确方法,可以避免在SpringBoot拦截器中处理RequestBody时的各种问题。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐