简体   繁体   English

有没有办法从Java servlet处理程序获取原始http请求流?

[英]Is there a way to get raw http request stream from Java servlet handler?

I am trying to put some logging to capture the raw http request coming to my application. 我试图将一些日志记录捕获到我的应用程序的原始http请求。 My Java code is inside a SpringMVC controller. 我的Java代码在SpringMVC控制器中。 I have access to the "HttpServletRequest" object. 我可以访问“HttpServletRequest”对象。 But I could not find a way to get the raw http request stream out of it. 但我找不到从中获取原始http请求流的方法。 There is a reader but only reads the post content. 有一个读者,但只阅读帖子内容。 What I want is the whole shebang, the url, the headers, the body. 我想要的是整个shebang,url,标题,身体。 Is there an easy way to do this? 是否有捷径可寻?

Thanks in advance. 提前致谢。

No. 没有。

The servlet provides no such API, and it would be hard to implement because (basically) you cannot read the same data twice from a Socket. servlet没有提供这样的API,并且很难实现,因为(基本上)你不能从Socket中读取两次相同的数据。 It is not difficult to get header information, but raw headers are impossible to capture within a servlet container. 获取头信息并不困难,但是在servlet容器中无法捕获原始头。 To get the bodies you need to capture them yourself as your application reads/writes the relevant streams. 当您的应用程序读取/写入相关流时,您需要自己捕获它们。

Your alternatives are: 您的替代方案是:

  1. Write your own server-side implementation of the HTTP protocol. 编写自己的HTTP协议的服务器端实现。 (Probably not right for your application.) (可能不适合您的申请。)

  2. You may be able to get the header information you need with filters, though they don't show the raw requests. 您可以使用过滤器获取所需的标题信息,但它们不会显示原始请求。

  3. Some servlet containers have request header logging; 一些servlet容器有请求头记录; eg with Tomcat there's a beast called the RequestDumperValve that you can configure in your "server.xml" file. 例如,对于Tomcat,有一个名为RequestDumperValve的野兽可以在“server.xml”文件中配置。

  4. Implement a proxy server that sits between the client and your "real" server. 实现位于客户端和“真实”服务器之间的代理服务器。

  5. Packet sniffing. 数据包嗅探。

Which is best depends on what you are really trying to achieve. 哪个最好取决于你真正想要实现的目标。

FOLLOWUP: 跟进:

If the "badness" is in the headers, the RequestDumperValve approach is probably the best for debugging. 如果标题中存在“badness”,则RequestDumperValve方法可能是调试的最佳方法。 Go to the "$CATALINA_HOME/conf/server.xml" file, search for "RequestDumperValve" and uncomment the element. 转到“$ CATALINA_HOME / conf / server.xml”文件,搜索“RequestDumperValve”并取消注释该元素。 Then restart Tomcat. 然后重启Tomcat。 You can also do the equivalent in your webapp's "context.xml" file. 您也可以在webapp的“context.xml”文件中执行等效操作。 The dumped requests and responses end up in "logs/catalina.out" by default. 转储的请求和响应默认以“logs / catalina.out”结尾。 Note that this will give a LOT of output, so you don't want to do this in production ... except as a last resort. 请注意,这将提供大量输出,因此您不希望在生产中执行此操作...除非作为最后的手段。

If the badness is in the content of a POST or PUT request, you'll need to modify your application to save a copy the content as it reads it from the input stream. 如果错误在POST或PUT请求的内容中,则您需要修改应用程序以在内容从输入流中读取内容时保存副本。 I'm not aware of any shortcuts for this. 我不知道有任何捷径。

Also, if you want to leave logging on for long periods, you'll probably need to solve the problem yourself by calling the HttpServletRequest API and logging headers, etc. The RequestDumperValve generates too much output, and dumps ALL requests not just the bad ones. 此外,如果您想长时间保持登录,您可能需要通过调用HttpServletRequest API和日志标头等来自己解决问题.RequestDumperValve生成太多输出,并转储所有请求而不仅仅是坏请求。

No, servlets provide no api to get at the raw request - you might need a sniffer like wireshark for that. 不,servlet没有提供api来获取原始请求 - 你可能需要像wireshark那样的嗅探器。

You can get at the parsed request headers and uri though: 您可以获取已解析的请求标头和uri:

etc. 等等

I managed to read my raw request in my webapplication deployed on Tomcat 5.5 我设法在我在Tomcat 5.5上部署的webapplication中读取我的原始请求

All I had to do is to read HttpServletRequest through my servlet/Spring controller using request.getInputStream() only. 我所要做的就是只使用request.getInputStream()通过我的servlet / Spring控制器读取HttpServletRequest。
It must be the first API approach to the request. 它必须是请求的第一个API方法。 before any filter or other command start to mass with the request that cause its completely reading by the webserver. 在任何过滤器或其他命令开始大量使用导致其完全由Web服务器读取的请求之前。

What's the problem with that approach? 这种方法有什么问题?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM