Skip to content

拦截器获取body参数 ​

一、重写httpservlet请求对象 ​

java
/**
 * getInputStream获取流 然后在流中获取数据 但是这个方法只能获取一次 重写httpservletrequestwrapper把request保存下来 用过滤器把保存的request填进去 就可以多次读取了
 */
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;
    }
}

二、增加过滤器 ​

java
/**
 * 过滤器,拦截请求并且转换request对象
 */
@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() {
    }
}

三、添加过滤器配置 ​

java
/**
 * 过滤器配置
 */
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebRequestFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }
}

四、拦截器 ​

java
/**
 * 数据验签拦截器
 */
@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;
    }
}