我正在处理旧版代码,需要打补丁。

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

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

到目前为止,我设法制作了一个包装,该包装从主体读取所有参数并覆盖了所有参数访问方法。但是,如果在我之前的链中的任何过滤器将尝试访问任何参数,则所有内容都会中断,因为ServletInputStream为空。

我可以以某种方式回避这个问题吗?可能有其他方法吗?

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

最佳答案

我找到的解决方案:

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

  • 需要一个将请求包装的过滤器。
  • 需要覆盖所有参数访问方法的自定义 HttpRequestWrapper 。请求主体应在构造函数中解析,并存储为字段。
  • 还应重新定义
  • getInputStream getReader 方法。它们的返回值取决于存储的请求正文。
  • 扩展的自定义类是ServletInputStream 所必需的,因为这是抽象的。

  • 这4个组合将使您可以使用 getParameter ,而不会干扰 getInputStream getReader 方法。

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

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

    10-04 18:01