解决 request.getInputStream() 与 request.getReader() 只能调用一次的问题

request.getInputStream() 与 request.getReader() 只能调用一次,因为是流,读取完就没了。

然而,有时我们可能会需要读取多次的场景,如在前端过滤器中,拦截请求数据并记录日志,记录日志后,请求继续向后传递,在后面的业务代码中,仍然可以继续取得请求的数据。

怎么办,办法总是有的,重写HttpServletRequestWrapper,自己实现一个Wrapper。

package com.abc.modules.sys.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.springframework.util.StreamUtils;

/**
* Created by jack on 2017/11/20 0020.
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

   private  byte[] body;

   public BodyReaderHttpServletRequestWrapper(HttpServletRequest request)
           throws IOException {
       super(request);
       body = StreamUtils.copyToByteArray(request.getInputStream());
   }

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

   @Override
   public ServletInputStream getInputStream() throws IOException {
       if(body == null){
           body = new byte[0];
       }
       final ByteArrayInputStream bais = new ByteArrayInputStream(body);
       return new ServletInputStream() {

           @Override
           public int read() throws IOException {
               return bais.read();
           }
       };
   }

}

在最前端的filter中,new一个自己的wrapper,并doChain继续向后传递即可。

package com.abc.modules.sys.utils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * Created by jack on 2017/11/20 0020.
 */
public class HttpServletRequestReplacedFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //Do nothing
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if(request instanceof HttpServletRequest) {
            requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
        }
        if(null == requestWrapper) {
            chain.doFilter(request, response);
        } else {
            chain.doFilter(requestWrapper, response);
        }

    }

    @Override
    public void destroy() {
        //Do nothing
    }

}

你可能感兴趣的:(解决 request.getInputStream() 与 request.getReader() 只能调用一次的问题)