Java构建可重复读取的Request和Response
为什么要可重复读取的req和resp
Request和Response本质上都是输入输出流,网络IO流。Request通过InputStream获取输入数据,Response通过OutputStream获取输出数据。因为流中的数据不是一直存储的,读取了就消失了,意思是只能读取一次。所以在像Servlet中拦截器这一部分,拦截Req和Resp的数据并读取,进行相应的操作,因此要对Req和Resp的数据进行保存一份,否者接下来就无法再次获取。
构建可重复读Request,应用在请求拦截器
public class RepeatedRequestWrapper extends HttpServletRequestWrapper { private final byte[] body;
public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException { super(request); request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); body = xxxUtil.reqToString(request.getInputStream()).getBytes("UTF-8"); }
@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(); }
@Override public int available() throws IOException { return body.length; }
@Override public boolean isFinished() { return false; }
@Override public boolean isReady() { return false; }
@Override public void setReadListener(ReadListener readListener) {
} }; } }
|
构建可重复读Response,应用在响应拦截器
public class RepeatedResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream byteArrayOutputStream;
private ServletOutputStream servletOutputStream;
public RepeatedResponseWrapper(HttpServletResponse response) { super(response); byteArrayOutputStream = new ByteArrayOutputStream(); servletOutputStream = new ServletOutputStream() { @Override public boolean isReady() { return false; }
@Override public void setWriteListener(WriteListener writeListener) {
}
@Override public void write(int b) throws IOException { response.getOutputStream().write(b); byteArrayOutputStream.write(b); } }; }
@Override public ServletOutputStream getOutputStream() throws IOException { return servletOutputStream; }
public byte[] toByteArray() { return byteArrayOutputStream.toByteArray(); } }
|