问题:
在 Java Servlet 过滤器中,尝试访问多个从 POST 请求正文检索的 HTTP 请求参数会导致第二个参数不可用。发生这种情况是因为消耗参数会消耗整个请求的参数。
问题:
有没有办法在不消耗它们的情况下读取请求参数?
答案:
替代解决方案:
使用切面创建自定义拦截器组件可以是一种替代解决方案,无需涉及过滤器链即可实现多次读取,并提高效率。
扩展 HttpServletRequestWrapper 解决方案:
要保留过滤器链中多次读取的请求正文参数,请扩展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); } // CachedServletInputStream implementation omitted for brevity }
过滤器用法:
在通过过滤器链传递原始请求之前将其包装在扩展类中:
public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { MultiReadHttpServletRequest multiReadRequest = new MultiReadHttpServletRequest((HttpServletRequest) request); // Perform multiple reads here chain.doFilter(multiReadRequest, response); } }
这种方法可以通过 getInputStream()、getReader() 和参数检索进行多次读取
更新较新的 ServletInputStream:
在缓存流实现中实现附加方法 isReady()、setReadListener() 和 isFinished() 以遵循更新的ServletInputStream 接口。
以上是如何多次读取HTTP POST请求参数而不消耗它们?的详细内容。更多信息请关注PHP中文网其他相关文章!