zoukankan      html  css  js  c++  java
  • 解决HttpServletRequest InputStream只能读取一次问题

    在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"));
        }
    }
  • 相关阅读:
    LOJ.6281.数列分块入门5(分块 区间开方)
    HDU.3571.N-dimensional Sphere(高斯消元 模线性方程组)
    POJ.2891.Strange Way to Express Integers(扩展CRT)
    Codeforces.100633J.Ceizenpok's formula(扩展Lucas)
    Some Formulas.
    洛谷.3807.[模板]卢卡斯定理(Lucas)
    CODEVS.3990.中国余数定理2(CRT)
    BZOJ.3667.Rabin-Miller算法(MillerRabin PollardRho)
    洛谷.1919.[模板]A*B Problem升级版(FFT)
    POJ.2065.SETI(高斯消元 模线性方程组)
  • 原文地址:https://www.cnblogs.com/eviltuzki/p/9186165.html
Copyright © 2011-2022 走看看