更新时间:
#可重复读 Request RepeatedlyRequestWrapper
开源项目 RequestWrapper 内部stream读取后就没了。
// 我们无法两次读取相同的InputStream 它是原始HttpServletRequest对象的包装。 当我们读取请求正文时,ContentCachingRequestWrapper会缓存内容供以后使用。 // requestWrapper.getContentAsByteArray()必须是在request.inputStream()的内容使用过后才能缓存请求中body的内容, // 下次需要再使用body只能使用此方法requestWrapper.getContentAsByteArray()才能再次获取body中的值。 // https://www.jianshu.com/p/977372059ae7
// OncePerRequestFilter 中
ContentCachingRequestWrapper wrapperRequest = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper wrapperResponse = new ContentCachingResponseWrapper(response);
chain.doFilter(wrapperRequest, wrapperResponse);
这里另一种方式,一直可以读。但这个流、缓存 对性能,内存有一定影响,大量请求时候
package org.javaboy.tienchin.common.filter;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.javaboy.tienchin.common.utils.http.HttpHelper;
/**
* 构建可重复读取inputStream的request
*
* @author tienchin
*/
public class RepeatedlyRequestWrapper 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 = HttpHelper.getBodyString(request).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) {
}
};
}
}