request.getInputStream()与request.getReader()只能调用一次,因为是流,读取完就没了。
然而,有时我们可能会需要读取多次的场景,如在前端过滤器中,拦截请求数据并记录日志,记录日志后,请求继续向后传递,在后面的业务代码中,仍然可以继续取得请求的数据。
怎么办,办法总是有的,重写HttpServletRequestWrapper,自己实现一个Wrapper。
代码:
package com.inspur.cloud.am; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import org.springframework.util.StreamUtils; public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{ private byte[] requestBody = null; public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); //缓存请求body try { requestBody = StreamUtils.copyToByteArray(request.getInputStream()); } catch (IOException e) { e.printStackTrace(); } } /** * 重写 getInputStream() */ @Override public ServletInputStream getInputStream() throws IOException { if(requestBody == null){ requestBody= new byte[0]; } final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; } /** * 重写 getReader() */ @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } }
在最前端的filter中,new一个自己的wrapper,并doChain继续向后传递即可。
参照:http://ayaoxinchao.iteye.com/blog/2110902