问题:
在 Java Servlet 过滤器中,访问 HTTP 请求POST 请求正文中的参数可能会导致这些参数稍后在过滤器链中不可用。出现这种情况是因为请求正文在初始读取期间被消耗。
解决方案:
要克服此问题并启用请求正文参数的多次读取,解决方案包括扩展 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(cachedBytes.toByteArray()); } @Override public BufferedReader getReader() throws IOException{ return new BufferedReader(new InputStreamReader(getInputStream())); } private void cacheInputStream() throws IOException { cachedBytes = new ByteArrayOutputStream(); IOUtils.copy(super.getInputStream(), cachedBytes); } /* An input stream which reads the cached 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 { MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request); doMyThing(multiReadRequest.getInputStream()); chain.doFilter(multiReadRequest, response); } }
这允许通过 getInputStream() 或 getReader() 多次读取请求正文
注意:
对于较新版本的 ServletInputStream 接口,需要在自定义输入流类中实现 isReady() 和 setReadListener() 等附加方法。详情请参阅答案中提供的链接。
以上是如何在 Java Servlet 过滤器中启用 POST 请求正文的多次读取?的详细内容。更多信息请关注PHP中文网其他相关文章!