
HttpServletRequest 的 getInputStream() 和 getReader() 都只能读取一次。
因为 我们使用@RequestBody 注解,读取body参数;而 又 写了拦截器,也需要将post请求,body数据拿出来。
由于@RequestBody 也是流的形式读取,流读了一次就没有了。
过滤器是优先于拦截器的, 我们写一个过滤器,在过滤器里面 把流数据 copy一份出来用,也就是复写一哈。
在拦截器上使用我们复写的流数据就行。
BodyWrapperFilter.java
- import javax.servlet.*;
- import javax.servlet.http.HttpServletRequest;
- import java.io.IOException;
-
-
- /**
- * @Author: JCccc
- * @Date: 2022-6-12 10:35
- * @Description:
- */
- public class BodyWrapperFilter implements Filter {
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- ServletRequest requestWrapper = null;
- if(servletRequest instanceof HttpServletRequest) {
- requestWrapper = new CustomHttpServletRequestWrapper((HttpServletRequest) servletRequest);
- }
- if(requestWrapper == null) {
- filterChain.doFilter(servletRequest, servletResponse);
- } else {
- filterChain.doFilter(requestWrapper, servletResponse);
- }
- }
- }
CustomHttpServletRequestWrapper.java
- import javax.servlet.ReadListener;
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import java.io.*;
- import java.nio.charset.StandardCharsets;
-
- /**
- * @Author: JCccc
- * @Date: 2022-6-12 10:36
- * @Description: 重写一个自己的 RequestWrapper 拿出body给自己用
- */
-
- public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {
- private byte[] body;
- public CustomHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
- super(request);
- BufferedReader reader = request.getReader();
- try (StringWriter writer = new StringWriter()) {
- int read;
- char[] buf = new char[1024 * 8];
- while ((read = reader.read(buf)) != -1) {
- writer.write(buf, 0, read);
- }
- this.body = writer.getBuffer().toString().getBytes();
- }
- }
- public String getBody(){
- return new String(body, StandardCharsets.UTF_8);
- }
- @Override
- public ServletInputStream getInputStream() {
- final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
- return new ServletInputStream() {
- @Override
- public boolean isFinished() {
- return false;
- }
- @Override
- public boolean isReady() {
- return false;
- }
-
- @Override
- public void setReadListener(ReadListener readListener) {
- }
-
- @Override
- public int read() {
- return byteArrayInputStream.read();
- }
- };
- }
- @Override
- public BufferedReader getReader() {
- return new BufferedReader(new InputStreamReader(this.getInputStream()));
- }
- }
WebApplicationConfig.java
- import org.springframework.boot.web.servlet.FilterRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * @Author: JCccc
- * @Date: 2022-6-23 10:52
- * @Description:
- */
- @Configuration
- public class WebApplicationConfig {
-
- @Bean
- BodyWrapperFilter getBodyWrapperFilter(){
- return new BodyWrapperFilter();
- }
- @Bean("bodyWrapperFilter")
- public FilterRegistrationBean<BodyWrapperFilter> checkUserFilter(BodyWrapperFilter bodyWrapperFilter) {
- FilterRegistrationBean<BodyWrapperFilter> registrationBean = new FilterRegistrationBean();
- registrationBean.setFilter(bodyWrapperFilter);
- registrationBean.addUrlPatterns("/*");
- registrationBean.setOrder(1);
- registrationBean.setAsyncSupported(true);
- return registrationBean;
- }
-
- }
然后就是在拦截器里面,如果我们想取出body,我们改成这样用:
CustomHttpServletRequestWrapper wrapper = (CustomHttpServletRequestWrapper) request; String nowParams = wrapper.getBody();
效果:
好的,这篇就到这。