1. 程式人生 > >解決HttpServletRequest InputStream只能讀取一次問題

解決HttpServletRequest InputStream只能讀取一次問題

vat har isf 字符 n) turn set super factory

在Filter中讀取inputSeream讀取一次之後就無法再次讀取,解決辦法如下:

public class LoggerHttpServletRequestWrapper extends HttpServletRequestWrapper {
   
   private final byte[] body;

   public LoggerHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
      super(request);
      body = StreamUtils.readBytes(request.getInputStream());
   }
   
   @Override
   public BufferedReader getReader() {
      return new BufferedReader(new InputStreamReader(getInputStream()));
   }
   
   @Override
   public ServletInputStream getInputStream() {
      final ByteArrayInputStream bais = 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 bais.read();
         }
      };
   }

}

  

調用如下

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    ServletRequest requestWrapper = null;
    if(request instanceof HttpServletRequest) {
        requestWrapper = new LoggerHttpServletRequestWrapper((HttpServletRequest) request);
        
if (((HttpServletRequest) request).getMethod().equals("POST")){ String path = ((HttpServletRequest) request).getServletPath(); String param = StreamUtils.streamToString(requestWrapper.getInputStream()); LoggerFactory.getLogger("filter."+path).info(param); }
else if (((HttpServletRequest) request).getMethod().equals("GET")){ String path = ((HttpServletRequest) request).getServletPath(); String queryString = ((HttpServletRequest) request).getQueryString(); LoggerFactory.getLogger("filter."+path).info(queryString); } } if(requestWrapper == null) { chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } }

工具類如下

public class StreamUtils {

    /**
     * @param inputStream inputStream
     * @return 字符串轉換之後的
     */
    public static String streamToString(InputStream inputStream) {
        try(BufferedReader br =new BufferedReader(new InputStreamReader(inputStream, "UTF-8"))) {
            StringBuilder builder = new StringBuilder();
            String output;
            while((output = br.readLine())!=null){
                builder.append(output);
            }
            return builder.toString();
        }  catch (IOException e) {
           throw new RuntimeException("Http 服務調用失敗",e);
        }
    }

    

    public static byte[] readBytes(ServletInputStream inputStream) {
        return streamToString(inputStream).getBytes(Charset.forName("UTF-8"));
    }
}

解決HttpServletRequest InputStream只能讀取一次問題