request 字节流只能读取一次
2021-08-22/2021-08-22
问题描述:
当我们使用拦截器或者过滤器读取和 request 的字节流之后,controller 中的 @RequestBody 报错,提示 request body 为空。
因为 request 的字节流只能读取一次,我们需要把此字节流存储起来,使其可以多次读取,利用 HttpServletRequestWrapper 对 request 进行封装。
继承 HttpServletRequestWrapper
1package com.rs.shiliu.filter;
2
3import org.springframework.util.StreamUtils;
4
5import javax.servlet.ReadListener;
6import javax.servlet.ServletInputStream;
7import javax.servlet.http.HttpServletRequest;
8import javax.servlet.http.HttpServletRequestWrapper;
9import java.io.BufferedReader;
10import java.io.ByteArrayInputStream;
11import java.io.IOException;
12import java.io.InputStreamReader;
13
14public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
15 private byte[] requestBody = null;
16
17 public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
18 super(request);
19 requestBody = StreamUtils.copyToByteArray(request.getInputStream());
20 }
21
22 @Override
23 public ServletInputStream getInputStream() throws IOException {
24 ByteArrayInputStream inputStream = new ByteArrayInputStream(requestBody);
25 return new ServletInputStream() {
26 @Override
27 public boolean isFinished() {
28 return inputStream.available() == 0;
29 }
30
31 @Override
32 public boolean isReady() {
33 return true;
34 }
35
36 @Override
37 public void setReadListener(ReadListener readListener) {
38
39 }
40
41 @Override
42 public int read() throws IOException {
43 return inputStream.read();
44 }
45 };
46 }
47
48 @Override
49 public BufferedReader getReader() throws IOException {
50 return new BufferedReader(new InputStreamReader(getInputStream()));
51 }
52}
添加过滤器,替换 request
1package com.rs.shiliu.filter;
2
3import org.slf4j.Logger;
4import org.slf4j.LoggerFactory;
5import org.springframework.stereotype.Component;
6
7import javax.servlet.*;
8import javax.servlet.annotation.WebFilter;
9import javax.servlet.http.HttpServletRequest;
10import java.io.IOException;
11
12@Component
13@WebFilter(urlPatterns = "/*")
14public class BodyReaderFilter implements Filter {
15 private static final Logger logger = LoggerFactory.getLogger(BodyReaderFilter.class);
16
17 @Override
18 public void init(FilterConfig filterConfig) throws ServletException {
19 Filter.super.init(filterConfig);
20 }
21
22 @Override
23 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
24 ServletRequest requestWrapper = null;
25 if (servletRequest instanceof HttpServletRequest) {
26 requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) servletRequest);
27 }
28 filterChain.doFilter(requestWrapper == null ? servletRequest : requestWrapper, servletResponse);
29 }
30
31 @Override
32 public void destroy() {
33 Filter.super.destroy();
34 }
35}
标题:request 字节流只能读取一次
作者:Rainsheep
地址:HTTPS://www.rainsheep.cn/articles/2021/08/22/1629610223095.html