ServletInputStream重复读取问题

    xiaoxiao2021-03-25  128

    本来是想实现tomcat的acess_log打印post请求参数。吐槽一下,tomcat功能和nginx差了好几条街。网上找了个方法,用tomcat的filter来实现。

    但是,写filter的时候,发现了ServletInputStream重复读取问题。

    网上找个几个方法,都不能直接用。综合网上的资料,根据自己的理解,终于能完美运行了。直接贴代码了,亲测能用。

    首先要写个BufferHttpServletRequestWrapper类,用来复制HttpServletRequest request。

    import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class BufferHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public BufferHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); InputStream is = request.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buff[] = new byte[ 1024 ]; int read; while( ( read = is.read( buff ) ) > 0 ) { baos.write( buff, 0, read ); } body = baos.toByteArray(); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; } }

    然后filter实现如下:

    import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; /** * Servlet Filter implementation class PostDataDumperFilter */ public class PostDataDumperFilter implements Filter { private FilterConfig filterConfig = null; /** * Default constructor. */ public PostDataDumperFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { this.filterConfig = null; } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (filterConfig == null) return; //备份HttpServletRequest ServletRequest requestWrapper = null; if(request instanceof HttpServletRequest) { requestWrapper = new BufferHttpServletRequestWrapper((HttpServletRequest) request); } //使用流 InputStream reader = requestWrapper.getInputStream(); ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(100); int i =0; byte [] b = new byte[100]; while((i = reader.read(b))!= -1){ byteOutput.write(b, 0, i); } request.setAttribute("post", new String(byteOutput.toByteArray())); // pass the request along the filter chain if(null == requestWrapper){ chain.doFilter(request, response); } else { chain.doFilter(requestWrapper, response); } } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { this.filterConfig = fConfig; } } 好了,就写到这里,如何配置filter,请看下边的参考资料吧。

    参考资料:

    http://liwx2000.iteye.com/blog/1542431 http://www.cnblogs.com/jiangxinnju/p/5709378.html 原理 http://www.cnblogs.com/wtstengshen/p/3186530.html tomcat的acess_log打印post请求参数,分析日志 http://blog.csdn.net/sc313121000/article/details/50503812

    转载请注明原文地址: https://ju.6miu.com/read-5321.html

    最新回复(0)