修改 HttpServletRequest body

2022-09-04 06:27:59

我正在研究遗留代码,需要制作一个补丁。

问题是:一个古老的应用程序发送了错误的HTTP POST请求。其中一个参数未进行 URL 编码。我知道这个参数总是排在最后,我知道它的名字。我现在正试图在tomcat内部运行的服务器端修复它。

此参数无法通过 HttpServletRequest 的标准 getParameter 方法访问,因为它的格式不正确。方法仅返回 null。但是当我通过ServletInputStream手动读取整个请求正文时,所有其他参数都消失了。看起来底层类无法解析ServletInputStream的内容,因为它已经耗尽了。

到目前为止,我已经设法制作了一个包装器,它从body读取所有参数并覆盖所有参数访问方法。但是,如果在我的链中的任何过滤器尝试访问任何参数,那么一切都会中断,因为ServletInputStream将是空的。

我能以某种方式回避这个问题吗?可能有不同的方法?

总而言之,如果我在筛选器中读取原始请求正文,参数将从请求中消失。如果我读取单个参数,ServletInputStream将变为空,手动处理将是不可能的。此外,通过 getParameter 方法读取格式错误的参数是不可能的。


答案 1

我发现的解决方案:

仅仅重新定义参数访问方法是不够的。必须做几件事。

  1. 需要一个过滤器来包装请求。
  2. 需要一个自定义的 HttpRequestWrapper 来覆盖所有参数访问方法。请求正文应在构造函数中解析并存储为字段。
  3. getInputStreamgetReader 方法也应该重新定义。它们返回值取决于存储的请求正文。
  4. 需要扩展ServletInputStream的自定义类,因为这个类是抽象的。

这 4 个组合将允许您使用 getParameter,而不会干扰 getInputStreamgetReader 方法。

请注意,手动请求参数解析可能会因多部分请求而变得复杂。但这是另一个话题。

为了澄清,我重新定义了参数访问方法,因为我的请求被损坏了,如问题中所述。你可能不需要它。


答案 2

与其重写方法,为什么不安装一个重写请求的 servlet 过滤器呢?

杰森·亨特(Jason Hunter)有一篇关于过滤器的非常好的文章


推荐