读取HTTPServletRequest的POST主体,然后在Tomcat中调用getParameter

rew*_*olf 9 java post tomcat servlets tomcat5.5

我的情况是我的应用程序需要检查POST请求的内容/数据/正文/有效负载而不更改后续getParameter调用的结果.

从inputStream中读取正文:

可以使用来自request.getInputStream或来自BufferedReader 的InputStream来读取正文request.getReader.

读取POST参数:

POST请求通常包括请求正文中的请求参数.这些可以使用getParameter.

问题:

第一个getParameter调用在内部解析inputStream并将所有参数插入到参数HashMap中.它要求inputStream仍然包含用于解析的内容.因此,无法检查内容并仍然有一个有效的getParameter调用.

建议(但不充分)的解决方案

创建一个请求包装器,缓存输入流并返回getInputStream的缓存.

我已经看到该解决方案在整个网络上建议,但它不起作用,因为getParameter实际上并没有调用getInputStream,而是指在请求对象中隐藏的原始inputBuffer.我已经尝试过,无论是在Servlet中还是使用过滤器

我能想到的唯一解决方案是重写getParameter以手动解析缓存的输入流.但这感觉就像一个坏主意.

有没有人有任何其他选择?(这是Tomcat 5.5)这感觉它应该是一个常见的用例; 我简直不敢相信它有多难.

rew*_*olf 1

正如 @caskey 所建议的,一个可能的解决方案是使用反射将 inputBuffer 替换为可重播的 inputbuffer。但我没有使用这种方法,因为它感觉很顽皮。

相反,我在过滤器中创建了一个请求包装器,它将输入流读取到字节数组中,并返回一个新的,该新InputStream的在内部使用ByteArrayInputStream该数组周围的所有getInputStream调用。

将输入流读取到字节数组后,我通过解析有效负载创建参数映射。我合并了超类的参数映射以支持带有查询参数的 GET 情况。我已经重写了所有 getParameter*() 方法来使用此参数映射。

我曾经apache.axis.utils.IOUtils.readFully轻松地将流读入字节数组。我目前正在使用javax.servlet.http.HttpUtils.parsePostData将数据解析为参数映射。HttpUtils.parsePostData实际上已被弃用,因此当我找到它时,我可能会用更好的版本替换它。

但这有效,耶!