背景
通常情況下,HttpServletRequst 中的 body 內(nèi)容只會讀取一次,但是可能某些情境下可能會讀取多次,由于 body 內(nèi)容是以流的形式存在,所以第一次讀取完成后,第二次就無法讀取了,一個典型的場景就是 Filter 在校驗完成 body 的內(nèi)容后,業(yè)務(wù)方法就無法繼續(xù)讀取流了,導(dǎo)致解析報錯
包裝 Request
既然直接不行,那么我們是否可以用裝飾器來修飾一下 request,使其可以包裝讀取的內(nèi)容,供多次讀取.比如
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
public String _body;
public MultiReadHttpServletRequest(HttpServletRequest request) throws IOException {
super(request);
StringBuffer sBuffer = new StringBuffer();
BufferedReader bufferedReader = request.getReader();
String line;
while ((line = bufferedReader.readLine()) != null) {
sBuffer.append(line);
}
_body = sBuffer.toString();
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(_body.getBytes());
return new ServletInputStream() {
@Override
public int read() {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
Filter中使用
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
//...some validate stuff against request
MultiReadHttpServletRequest requestWrapper = new MultiReadHttpServletRequest(request);
filterChain.doFilter(request, response);
}