一尘不染

阅读HTTPServletRequest的POST正文,然后在Tomcat中调用getParameter

tomcat

我处于一种情况,我的应用程序需要检查POST请求的内容/数据/正文/有效负载,而无需更改后续getParameter调用的结果。

从inputStream读取正文:

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

读取POST参数:

POST请求通常在请求正文中包含请求参数。可以使用检索这些getParameter

问题:

第一次getParameter调用在内部解析inputStream并将所有参数插入参数HashMap中。它要求inputStream仍然包含要解析的内容。因此,人们无法检查内容,而仍然可以正常使用getParameter调用。

拟议(但不足)的解决方案

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

我已经看到该解决方案在整个Web上都提出了建议,但是它没有用,因为getParameter实际上并没有调用getInputStream,而是引用了埋在请求对象中的原始inputBuffer。我已经尝试过,无论是在Servlet中还是使用过滤器

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

有人有其他可行的选择吗?(这是Tomcat 5.5)这感觉应该是一个普通的用例。我不敢相信这有多难。


阅读 234

收藏
2020-06-16

共1个答案

一尘不染

正如@caskey所建议的那样,可能的解决方案是使用反射将可重播的输入缓冲区替换为输入缓冲区。但是我没有使用那种方法,因为它很顽皮。

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

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

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

但这有效,是的!

2020-06-16