request.getInputStream()只能读取一次的解决方案

最近,接手一个相关项目,而前端传递参数都是已json方式,在拦截器中要对某个必传参数进行校验,我就使用request.getInputStream(),这样到了controller时,对象属性都为空,后来确定问题是由于request.getInputStream()只能够读取一次。但是在实际的开发中往往需要多次读取。这样就需要我们将流写入进去,提供后续使用。方法可能有很多,
1:创建RequestHelper类获取流中的数据。
 
public class RequestHelper{

    /**
     * @param request
     * @return
     */
    private static Logger logger = LoggerFactory.getLogger(RequestHelper.class);
    public static String getBodyString(ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = request.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            logger.warn("getBodyString出现问题!");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
}
2:继承HttpServletRequestWrapper类
 
public class EbHttpServletWrapper extends HttpServletRequestWrapper {

    private Logger logger = LoggerFactory.getLogger(EbHttpServletWrapper.class);
    private String encoding = "UTF-8";
    private byte[] requestBodyIniBytes;

    public EbHttpServletWrapper(HttpServletRequest request) throws IOException {
        super(request);
        ServletInputStream stream = request.getInputStream();
        String requestBody = StreamUtils.copyToString(stream, Charset.forName(encoding));
        requestBodyIniBytes = requestBody.getBytes(encoding);

    }



    public ServletInputStream getInputStream() {
        final ByteArrayInputStream in;
        in = new ByteArrayInputStream(requestBodyIniBytes);

        return new ServletInputStream() {
            @Override
            public int read() throws IOException {

                return in.read();
            }
        };
    }
}

3:在过滤器中加入如下代码(如果是文件类型,可能会有问题,将其排除,不再拦截)

 
public class RequestFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request1 = (HttpServletRequest) request;
        if(Objects.isNull(request1.getHeader("Content-Type")) || request1.getHeader("Content-Type").contains("multipart/form-data;")){
            chain.doFilter(request,response);
        }else {
            chain.doFilter(new EbHttpServletWrapper(request1), response);
        }
    }

    @Override
    public void destroy() {

    }
}
谢谢阅览。

猜你喜欢

转载自blog.csdn.net/fz13768884254/article/details/81365203