spring boot项目拦截器拦截请求后使用request.getInputStream(); 在后续的方法中无法获取到参数的问题

问题点:在项目使用拦截器拦截对外请求并进行业务操作在过成功发现request.getInputStream();在被使用一次后会被关闭
1.首先定义自己的 HttpServletRequestWrapper
package com.safesoft.config.interceotor;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {


    private final byte[] body;

    public CustomHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);

        try (InputStream inputStream = request.getInputStream();
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
            body = byteArrayOutputStream.toByteArray();

        } catch (IOException e) {
            throw new RuntimeException("Error reading the request body", e);
        }
    }

    @Override
    public ServletInputStream getInputStream() {

        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() {
        InputStreamReader inputStreamReader = new InputStreamReader(getInputStream(), StandardCharsets.UTF_8);
        return new BufferedReader(inputStreamReader);
    }

    public String getBody() {
        return new String(body, StandardCharsets.UTF_8);
    }
}

上述方法确实没有问题但并不完整在进行包装过后我们需要在过滤器中加入我们创建CustomHttpServletRequestWrapper

1.其次实现Filter
public class CustomFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        CustomHttpServletRequestWrapper customHttpServletRequestWrapper = null;
        try {
            HttpServletRequest req = (HttpServletRequest)request;
            customHttpServletRequestWrapper = new CustomHttpServletRequestWrapper(req);
        }catch (Exception e){
            log.warn("customHttpServletRequestWrapper Error:", e);
        }
        chain.doFilter((Objects.isNull(customHttpServletRequestWrapper) ? request : customHttpServletRequestWrapper), response);
    }
}
2.最后我们在WebMvcConfig中去注册我们的过滤器
public class WebMvcConfig implements WebMvcConfigurer {
	 
	
	@Bean
    public FilterRegistrationBean<CustomFilter> servletRegistrationBean() {
        CustomFilter customFilter = new CustomFilter();
        FilterRegistrationBean<CustomFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(customFilter);
        bean.setName("customFilter");
        bean.addUrlPatterns("/*");
        bean.setOrder(Ordered.LOWEST_PRECEDENCE);
        return bean;
    }
    
    
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐