代码之家  ›  专栏  ›  技术社区  ›  rewolf

读取HTTPServlet请求的POST正文,然后在Tomcat中调用getParameter

  •  9
  • rewolf  · 技术社区  · 11 年前

    我的应用程序需要在不更改后续getParameter调用结果的情况下检查POST请求的内容/data/body/有效负载。

    从inputStream中读取正文:

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

    正在读取POST参数:

    POST请求通常在请求的主体中包括请求参数。这些可以使用 getParameter .

    问题:

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

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

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

    我在网上看到过这个解决方案,但它不起作用,因为 获取参数 实际上并没有打电话 getInputStream ,但引用了隐藏在请求对象中的原始inputBuffer。我已经尝试过了,无论是从Servlet内部还是通过使用过滤器

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

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

    2 回复  |  直到 11 年前
        1
  •  1
  •   caskey    11 年前

    (这是一只相当古老的假猫,我想升级到更现代的假猫是不可能的。)

    您想要做的事情需要截取封装底层InputStream的具体HttpServlet响应对象的构造。将InputStream封装在推回输入流(或等效流)中是必要的。

    Tomcat5.5太旧了,我甚至想不出如何“正常”实现这一点,但也许您可以编写一个过滤器,使用反射来访问并交换具体请求对象中的InputStream对象。

        2
  •  1
  •   rewolf    11 年前

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

    相反,我在过滤器中创建了一个请求包装器,它将输入流读取到字节数组中,并返回一个新的 InputStream 内部使用 ByteArrayInputStream 围绕着那个阵列 getInputStream 电话。

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

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

    但这是有效的,耶!