本文介绍了阅读HTTPServletRequest的POST正文,然后在Tomcat中调用getParameter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am in the situation where my application needs to inspect the content/data/body/payload of a POST request without changing the results of subsequent getParameter calls.

从inputStream读取正文:

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

The body can be read using the InputStream from request.getInputStream or BufferedReader from request.getReader.

读取POST参数:

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

POST requests typically include request parameters in the body of the request. These can be retrieved using getParameter.

问题:

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

the first getParameter call internally parses the inputStream and inserts all parameters into a parameter HashMap. It requires the inputStream to still contain the contents for parsing. Thus one cannot inspect the content and still have a working getParameter call.

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

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

Create a request wrapper that caches the inputstream and returns the cache for getInputStream.

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

I've seen that solution suggested all over the web, but it doesn't work, because getParameter doesn't actually call getInputStream, but refers to the original inputBuffer buried in the request object. I've tried it, both from within the Servlet and by using a filter

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

The only solution I can think of involves rewriting getParameter to actually parse the cached inputstream manually. But this feels like a bad idea.

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

Does anybody have any alternative that works? (This is Tomcat 5.5) This feels like it should be a common use-case; I can't believe how difficult it is.

推荐答案

如@caskey所建议,一种可能的解决方案是使用反射用可重播的输入缓冲区替换inputBuffer.但是我并没有使用那种调皮的方法.

As suggested by @caskey, a possible solution would be to use reflection to replace the inputBuffer with a replayable inputbuffer. But I did not use that approach as it felt naughty.

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

Instead I created a request wrapper in a filter which reads the inputstream into a byte array and returns a new InputStream that internally uses a ByteArrayInputStream around that array for all getInputStream calls.

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

After reading the inputstream to the byte array, I create a parameter map by parsing the payload. I merged the superclass' parameter map in to support GET cases with query parameters. I've overridden all the getParameter*() methods to use this parameter map.

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

I used apache.axis.utils.IOUtils.readFully to easily read the stream in to the byte array. And I'm currently using javax.servlet.http.HttpUtils.parsePostData to parse the data into parameter map. HttpUtils.parsePostData is actually deprecated, so I'll likely replace it with a better version when I find it.

但这行得通,是的!

这篇关于阅读HTTPServletRequest的POST正文,然后在Tomcat中调用getParameter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 14:17