在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(); ????????} ?????}; ??}}
调用如下
@Overridepublic 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只能读取一次问题
原文地址:https://www.cnblogs.com/eviltuzki/p/9186165.html