有没有一种方法可以从Java servlet处理程序中获取原始的HTTP请求流?

3
我正在尝试添加一些日志记录来捕获发送到我的应用程序的原始HTTP请求。我的Java代码位于SpringMVC控制器内部。我可以访问"HttpServletRequest"对象,但找不到一种方法将原始的HTTP请求流从其中提取出来。它有一个阅读器,但只能读取发布内容。我想要的是全部,包括URL、标题和正文。有没有简单的方法可以做到这一点?
提前感谢您的回答。
3个回答

5

第一点:

Servlet没有提供这样的API,而且很难实现,因为(基本上)你不能从Socket中读取相同的数据两次。获取头信息不难,但是在servlet容器内无法捕获原始头信息。如果要获取正文,则需要在应用程序读取/写入相关流时自行捕获。

您的替代方案是:

  1. 编写自己的HTTP协议服务器端实现。(可能不适合您的应用程序。)

  2. 您可以使用过滤器获取所需的标头信息,尽管它们不显示原始请求。

  3. 某些servlet容器具有请求头日志记录;例如,使用Tomcat可以在“server.xml”文件中配置称为RequestDumperValve的工具。

  4. 实现一个代理服务器,位于客户端和您的“真实”服务器之间。

  5. 包嗅探。

最佳选择取决于您真正想要实现什么。

后续处理:

如果“坏事”出现在标题中,则RequestDumperValve方法可能是调试的最佳选择。转到“$CATALINA_HOME/conf/server.xml”文件,搜索“RequestDumperValve”,并取消注释该元素。然后重新启动Tomcat。您还可以在Web应用程序的“context.xml”文件中执行相同的操作。转储的请求和响应默认保存在“logs/catalina.out”中。请注意,这将产生大量输出,因此除非万不得已,否则不要在生产中使用。

如果坏事出现在POST或PUT请求的内容中,则需要修改应用程序以便在从输入流读取内容时保存副本。我不知道有什么捷径可以做到这一点。

此外,如果您想长时间保留日志记录,则可能需要通过调用HttpServletRequest API自己解决问题并记录标头等。RequestDumperValve生成太多输出,并且转储所有请求而不仅仅是坏请求。


谢谢提供的信息。我想要实现的是在出现错误/错误请求时记录完整的请求。我会按照nos建议的去做。 - savanna

4
不,servlets没有提供获取原始请求的api - 你可能需要像wireshark这样的嗅探器来实现。但是,您可以访问解析后的请求头和uri:getHeaderNames() getRequestURI() 等等。

实际上,我听说ASP有一个解决方案,它的魔力在于:Request.ServerVariables["ALL_RAW"],但这不是Java Servlet。哦,好吧。 - Alz

0

我成功读取了部署在Tomcat 5.5上的Web应用程序中的原始请求。



我所需要做的就是通过我的Servlet/Spring控制器使用request.getInputStream()只读取HttpServletRequest。
这必须是请求的第一个API方法,在任何过滤器或其他命令开始干扰请求并导致Web服务器完全读取之前。

这种方法有什么问题吗?


1
request.getInputStream() 只会获取请求的主体,而不是头部。 OP 想要“所有东西,包括 URL、头部和主体”。 - CFL_Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接