HttpServletRequest只能读取一次
第一种方案:继承HttpServletRequestWrapper
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
private ByteArrayOutputStream cachedBytes;
public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (cachedBytes == null)
cacheInputStream();
return new CachedServletInputStream();
}
@Override
public BufferedReader getReader() throws IOException{
return new BufferedReader(new InputStreamReader(getInputStream()));
}
private void cacheInputStream() throws IOException {
/*
* 为了能多次读取,使用 apache.commons IOUtils 缓存inputstream
*/
cachedBytes = new ByteArrayOutputStream();
IOUtils.copy(super.getInputStream(), cachedBytes);
}
/* input stream 可以读取缓存的request body */
private static class CachedServletInputStream extends ServletInputStream {
private final ByteArrayInputStream buffer;
public CachedServletInputStream(byte[] contents) {
this.buffer = new ByteArrayInputStream(contents);
}
@Override
public int read() {
return buffer.read();
}
@Override
public boolean isFinished() {
return buffer.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
throw new RuntimeException("Not implemented");
}
}
}
使用示例
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/* 把request封装进MultiReadHttpServletRequest */
MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request);
/*
* 读取inputstream,执行自己的业务代码
*/
doMyThing(multiReadRequest.getInputStream());
//可以多次使用
anotherUsage(multiReadRequest.getReader());
chain.doFilter(multiReadRequest, response);
}
}
第二种方案:使用ContentCachingRequestWrapper
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) request);
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);
try {
chain.doFilter(requestWrapper, responseWrapper);
} finally {
String requestBody = new String(requestWrapper.getContentAsByteArray());
String responseBody = new String(responseWrapper.getContentAsByteArray());
// 使用了 requestBody后,必须执行这一行
responseWrapper.copyBodyToResponse();
// 使用了 requestBody执行自己的业务逻辑,例如:写日志
}
}
}
Loading...