Skip to content

拦截器获取body参数

一、重写httpservlet请求对象

/**
 * getInputStream获取流 然后在流中获取数据 但是这个方法只能获取一次 重写httpservletrequestwrapper把request保存下来 用过滤器把保存的request填进去 就可以多次读取了
 * @Author lcy
 * @Date 2022/5/24 10:48
 */
public class WebRequestWrapper extends HttpServletRequestWrapper {

    /** body参数 */
    private String body;

    public WebRequestWrapper(HttpServletRequest request) throws IOException{
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer,0,bytesRead);
                }
            }
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());

        ServletInputStream servletInputStream = 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();
            }
        };
        return servletInputStream;

    }

    @Override
    public BufferedReader getReader() throws IOException{
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody(){
        return this.body;
    }

    public void setBody(String body){
        this.body = body;
    }
}

二、增加过滤器

/**
 * 过滤器,拦截请求并且转换request对象
 * @Author lcy
 * @Date 2022/5/24 10:50
 */
@Order(-1)
@WebFilter(filterName = "WebRequestFilter", urlPatterns = "/*")
public class WebRequestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig){
    }

    @Override
    public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain chain)
    throws IOException, ServletException{
        ServletRequest request = null;
        //转换请求对象
        if (servletRequest instanceof HttpServletRequest) {
            request = new WebRequestWrapper((HttpServletRequest)servletRequest);
        }
        if (request == null) {
            chain.doFilter(servletRequest,servletResponse);
        } else {
            chain.doFilter(request,servletResponse);
        }
    }

    @Override
    public void destroy(){
    }
}

三、添加过滤器配置

/**
 * 过滤器配置
 * @Author lcy
 * @Date 2022/5/24 12:04
 */
@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean filterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebRequestFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }
}

四、拦截器

/**
 * 数据验签拦截器
 * @Author lcy
 * @Date 2021/5/6 15:26
 */
@Component
@Slf4j
public class RequestInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler){
        //getInputStream获取流,然后在流中获取数据.但是这个方法只能获取一次,重写HttpServletRequestWrapper把request保存下来,用过滤器把保存的request填进去 就可以多次读取了
        if (request instanceof WebRequestWrapper) {
            WebRequestWrapper requestWrapper = (WebRequestWrapper)request;
            String body = requestWrapper.getBody();
            //将处理后的body放回
            requestWrapper.setBody(body);
        }
        return true;
    }

}