HttpServletRequestWrapper存储Request
HTTP请求的输入流只能被读取一次,再想获取就获取不到了,那有什么方法可以缓存呢,我们可以自定义一个HttpServletRequest,或者是想在请求参数中统一添加或删除参数也可以使用此类进行改造,然后通过过滤器继续向下流转。废话不多说上代码。
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {private final Map<String, String[]> parameterMap;private final byte[] cachedBody;public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {super(request);this.parameterMap = request.getParameterMap();this.cachedBody = IoUtil.readBytes(request.getInputStream(), false);}@Overridepublic String getParameter(String name) {String[] values = this.parameterMap.get(name);return (values != null && values.length > 0) ? values[0] : null;}@Overridepublic Map<String, String[]> getParameterMap() {return Collections.unmodifiableMap(this.parameterMap);}@Overridepublic String[] getParameterValues(String name) {return this.parameterMap.get(name);}@Overridepublic ServletInputStream getInputStream() throws IOException {return new CachedBodyServletInputStream(this.cachedBody);}@Overridepublic BufferedReader getReader() throws IOException {ByteArrayInputStream bais = new ByteArrayInputStream(this.cachedBody);return new BufferedReader(new InputStreamReader(bais));}public byte[] getCachedBody() {return this.cachedBody;}private static class CachedBodyServletInputStream extends ServletInputStream {private final ByteArrayInputStream buffer;public CachedBodyServletInputStream(byte[] contents) {this.buffer = new ByteArrayInputStream(contents);}@Overridepublic int read() throws IOException {return buffer.read();}@Overridepublic boolean isFinished() {return buffer.available() == 0;}@Overridepublic boolean isReady() {return true;}@Overridepublic void setReadListener(ReadListener listener) {throw new UnsupportedOperationException();}}
}
这里也要提到一个小知识点,当浏览器或其他客户端向服务器发送HTTP请求时,请求可以包含请求头和请求体。对于GET请求,通常没有请求体,而对于POST请求,请求体中可能包含了表单数据、JSON对象或其他类型的数据。request.getInputStream()
方法允许开发者读取这些数据。