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()
方法允許開發者讀取這些數據。