发布于 3年前

Spring MVC重复多次读取请求的Body

我们知道,HttpServletRequest的InputStream流只能读取一次,不能重复读取。在Spring MVC中,它提供了类ContentCachingRequestWrapper,它会对原始的HttpServletRequest对象进行包装。 当我们调用request body时,ContentCachingRequestWrapper会把request body的内容进行缓存,这样我们就可以在后续的使用重复读取request body。

创建ContentCachingRequestWrapper

为了使用ContentCachingRequestWrapper,需要我们创建一个web filter,示例如下:

@Component
public class CachingRequestBodyFilter extends GenericFilterBean {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
      throws IOException, ServletException {
        HttpServletRequest currentRequest = (HttpServletRequest) servletRequest;
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(currentRequest);
        chain.doFilter(wrappedRequest, servletResponse);
    }
}

在Web filter的doFilter方法里,创建ContentCachingRequestWrapper对request做包装。

使用ContentCachingRequestWrapper

接下来我们就可以在Controller里调用ContentCachingRequestWrapper的方法获取request body。示例如下:

@RestController
public class GreetController {
    @PostMapping("/greet")
    public String greet(@RequestBody String name, HttpServletRequest request) {
        ContentCachingRequestWrapper requestWrapper = (ContentCachingRequestWrapper) request;
        String requestBody = new String(requestWrapper.getContentAsByteArray());
        return "Greetings " + requestBody;
    }

这和普通的Controller写法是一样的,只是在获取request body的内容时,调用的是ContentCachingRequestWrapper的getContentAsByteArray方法,它会返回request Body的原始字节。

©2020 edoou.com   京ICP备16001874号-3