Bootstrap

springboot中自定义过滤器request的getReader和getInputStream()方法来获取了流数据但是流读取一次后就关闭了在filter中读取了以后controller中拿不到了

如果你在过滤器中读取了请求体的流数据,导致在控制器(Controller)中无法再次获取请求体数据的问题,可以通过使用ServletRequestWrapper类来解决。ServletRequestWrapper是一个Servlet请求包装器,可以允许多次读取请求体数据。以下是一个示例代码:

java
Copy code
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.IOException;

public class CustomRequestWrapper extends HttpServletRequestWrapper {
    private final String requestBody;

    public CustomRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        requestBody = getRequestBody(request);
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(super.getReader());
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());
        return new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
    }

    private String getRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;

        try {
            bufferedReader = request.getReader();
            char[] charBuffer = new char[128];
            int bytesRead;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }

        return stringBuilder.toString();
    }
}
在自定义过滤器中,将原始请求对象替换为CustomRequestWrapper对象,并将该包装后的请求对象传递给FilterChain的doFilter()方法:

java
Copy code
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter("/*")
public class CustomFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        CustomRequestWrapper requestWrapper = new CustomRequestWrapper(httpRequest);

        chain.doFilter(requestWrapper, response);
    }

    // 其他方法的实现略...
}
通过以上示例代码,你可以在自定义过滤器中读取请求体数据并创建一个可重复读取的ServletRequestWrapper对象。这样,在控制器(Controller)中就可以再次获取请求体数据了。请确保在适当的时机手动关闭使用的资源。

;