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"));
        }
    }
  • 相关阅读:
    IbatisNet 快速开发使用 之一
    C#开发和调用Web Service
    如何构建银行数据仓库
    SQLSREVER如何创建和使用动态游标
    一个sql语句,包含有几乎所有标准查询语法
    深入研究SQL结构化查询语言中的LIKE语句
    数据库正规化和设计技巧
    黑客攻破SQL服务器系统的十种方法
    实用的存储过程
    数据库人员手边系列:SQL Server常见连接错误
  • 原文地址:https://www.cnblogs.com/eviltuzki/p/9186165.html
Copyright © 2011-2022 走看看