【问题标题】:Read HTTPServletRequest's POST body AND then call getParameter in Tomcat阅读 HTTPServletRequest 的 POST 正文,然后在 Tomcat 中调用 getParameter
【发布时间】:2013-08-31 14:45:43
【问题描述】:

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

从 inputStream 中读取正文:

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

读取 POST 参数:

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

问题:

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

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

创建一个请求包装器,用于缓存输入流并为 getInputStream 返回缓存。

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

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

有没有人有任何可行的替代方案? (这是Tomcat 5.5)这感觉应该是一个常见的用例;我不敢相信这有多么困难。

【问题讨论】:

  • 该问题的答案不是解决方案。我已经实现了它,但未能解决问题。从那时起,我阅读了 tomcat 源代码并意识到 getParameter 不会调用 getInputStream,正如我上面所说的,因此不会从流的缓存版本中读取。见grepcode.com/file/repo1.maven.org/maven2/tomcat/catalina/5.5.23/…我不知道为什么人们似乎发现它是一个解决方案。
  • 方法getParameter调用getInputStream。首先,getParameter 调用parseParameters,然后parseParameters 调用readPostBody,然后readPostBody 调用getInputStream

标签: java tomcat servlets post tomcat5.5


【解决方案1】:

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

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

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

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

但这行得通,耶!

【讨论】:

    【解决方案2】:

    (这是一个相当旧的 tomcat,我假设升级到更现代的不是一种选择。)

    您想要做的将需要拦截包装底层 InputStream 的具体 HttpServletResponse 对象的构造。有必要将该 InputStream 包装在一个推回输入流(或等效的)中。

    Tomcat 5.5 太老了,我什至无法想象“正常”如何实现,但也许您可以编写一个过滤器,使用反射来到达并交换具体请求对象中的 InputStream 对象。

    【讨论】:

    • 是的。你对反射的想法很满意。我们也想出了它。不过,我选择了一种不同的方法——在支持重放输入流的过滤器中创建请求包装器。然后,我重写了 getParameter*() 方法以从通过解析输入流/有效负载创建的地图中读取数据。
    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 2021-10-21
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 2012-07-10
    相关资源
    最近更新 更多