Java 复制HttpServletRequest InputStream的方法 只需2步轻松搞定
你可能很疑惑,为什么request对象中的InputStream或者Reader只能使用一次?
原理很简单,可以把流比喻成水,request里面的inputStream就好比杯子中的水。试问杯子中的水倒掉之后还能继续倒吗?当然不能滴!InputStream里面有做指针和同步处理,一旦指针到了末尾是不会回来的。那么我们怎么拷贝request body里面的数据呢,当然我们得找一种可以复制的存储方式了,比如String,可以先把request 的inputStream转成String,然后又把String转成byte[] 存回去就是了,String对象我们可以无限使用。
好了,废话不多说,上代码:
1. 先定义一个过滤器,过滤器自己先配置好哈,然后我们在过滤器的doFilter方法中做以下操作:
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { try { MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) servletRequest); System.out.println("RequestBody:" + requestWrapper.getBodyString()); filterChain.doFilter(requestWrapper, servletResponse); } catch (IOException e) { e.printStackTrace(); } }
2. 这是MyHttpServletRequestWrapper类,主要是储存body string,和给request对象塞byte[]:
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; private String bodyString; public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); this.bodyString = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8")); body = bodyString.getBytes("UTF-8"); } public String getBodyString() { return this.bodyString; } @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 boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() throws IOException { return bais.read(); } }; } }
OK, 简单吧,你可以尝试一下了。
网络上志同道合,我们一起学习网络安全,一起进步,QQ群:694839022