有没有办法从 Java servlet 处理程序获取原始 http 请求流?
我正在尝试进行一些日志记录来捕获传入我的应用程序的原始 http 请求。我的 Java 代码位于 SpringMVC 控制器内。我可以访问“HttpServletRequest”对象。但我找不到一种方法来从中获取原始 http 请求流。有读者但只阅读帖子内容。我想要的是整个 shebang、url、标题、正文。有没有简单的方法可以做到这一点?
提前致谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不。Servlet
不提供这样的 API,并且很难实现,因为(基本上)您无法从 Socket 读取相同的数据两次。获取标头信息并不困难,但在 servlet 容器内无法捕获原始标头。要获取主体,您需要在应用程序读取/写入相关流时自行捕获它们。
您的替代方案是:
编写您自己的 HTTP 协议的服务器端实现。 (可能不适合您的应用程序。)
您也许能够通过过滤器获取所需的标头信息,尽管它们不显示原始请求。
一些servlet容器有请求头日志记录;例如,在 Tomcat 中,有一个名为 RequestDumperValve 的野兽,您可以在“server.xml”文件中配置它。
实现位于客户端和“真实”服务器之间的代理服务器。
数据包嗅探。
哪个最好取决于您真正想要实现的目标。
后续:
如果“错误”位于标头中,则 RequestDumperValve 方法可能是最好的调试方法。转到“$CATALINA_HOME/conf/server.xml”文件,搜索“RequestDumperValve”并取消注释该元素。然后重新启动Tomcat。您还可以在 web 应用程序的“context.xml”文件中执行相同的操作。默认情况下,转储的请求和响应最终位于“logs/catalina.out”中。请注意,这将产生大量输出,因此您不想在生产中执行此操作......除非作为最后的手段。
如果问题出在 POST 或 PUT 请求的内容中,则您需要修改应用程序以在从输入流读取内容时保存内容副本。我不知道这有什么捷径。
另外,如果您想长时间保持登录状态,您可能需要通过调用 HttpServletRequest API 和记录标头等自行解决问题。RequestDumperValve 会生成过多的输出,并转储所有请求,而不仅仅是错误的请求。
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. It is not difficult to get header information, but raw headers are impossible to capture within a servlet container. To get the bodies you need to capture them yourself as your application reads/writes the relevant streams.
Your alternatives are:
Write your own server-side implementation of the HTTP protocol. (Probably not right for your application.)
You may be able to get the header information you need with filters, though they don't show the raw requests.
Some servlet containers have request header logging; e.g. with Tomcat there's a beast called the RequestDumperValve that you can configure in your "server.xml" file.
Implement a proxy server that sits between the client and your "real" server.
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. Go to the "$CATALINA_HOME/conf/server.xml" file, search for "RequestDumperValve" and uncomment the element. Then restart Tomcat. You can also do the equivalent in your webapp's "context.xml" file. The dumped requests and responses end up in "logs/catalina.out" by default. 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. 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.
不,servlet 不提供 api 来获取原始请求 - 您可能需要像wireshark 这样的嗅探器。
您可以获取已解析的请求标头和 uri:
等。
No, servlets provide no api to get at the raw request - you might need a sniffer like wireshark for that.
You can get at the parsed request headers and uri though:
etc.
我设法在 Tomcat 5.5 上部署的 Web 应用程序中读取原始请求
我所要做的就是通过我的 servlet/Spring 控制器读取 HttpServletRequest
仅使用 request.getInputStream() 。
它必须是请求的第一个 API 方法。在任何过滤器或其他命令开始聚集请求之前,导致其被网络服务器完全读取。
这种方法有什么问题吗?
I managed to read my raw request in my webapplication deployed on Tomcat 5.5
All I had to do is to read HttpServletRequest through my servlet/Spring controller
using request.getInputStream() only.
It must be the first API approach to the request. before any filter or other command start to mass with the request that cause its completely reading by the webserver.
What's the problem with that approach?