记录 Java 应用程序的所有网络交互
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18512522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Log all network interactions of Java application
提问by Hnatt
I have a monstrous Java app (a client of little-known application server GNUEnterprise) and its source, which I can compile back after making some changes to it. The app uses network heavily and I need to monitor each request and response. I could use a sniffer like Wireshark, but the application works with its server over SSL, so not knowing SSL-certificate's private key any sniffed traffic is pretty useless.
我有一个可怕的 Java 应用程序(鲜为人知的应用程序服务器 GNUEnterprise 的客户端)及其源代码,我可以在对其进行一些更改后重新编译。该应用程序大量使用网络,我需要监视每个请求和响应。我可以使用像 Wireshark 这样的嗅探器,但是该应用程序通过 SSL 与其服务器一起工作,因此不知道 SSL 证书的私钥,任何嗅探到的流量都非常无用。
What can I do to make every request and response to be logged from the application itself? I need to see all sent and received headers. I don't want to alter all code responsible for network interaction. What I want is to put a code like
我该怎么做才能从应用程序本身记录每个请求和响应?我需要查看所有发送和接收的标头。我不想更改所有负责网络交互的代码。我想要的是放一个代码
Network.setDefaultLogger(myCustomLoggerInstance);
somewhere near start of the app and then in the myCustomLoggerInstance
do all the logging I need.
在应用程序开始附近的某个地方,然后在myCustomLoggerInstance
做我需要的所有日志记录。
Also, given all network operations are made with URLConnection
s, I can get response headers with con.getHeaderFields()
and request headers with con.getRequestProperties()
. But why cookies aren't there? How to dump sent and received cookies in the same way?
此外,鉴于所有网络操作都是使用URLConnection
s 进行的,我可以con.getHeaderFields()
使用con.getRequestProperties()
. 但是为什么没有cookies呢?如何以相同的方式转储发送和接收的 cookie?
EDIT: What I'm trying to reach is to mimic RPC-application's communication with it's server over SSL, say, using curl
. For this I need to get detailed log of app's network traffic.
编辑:我想要达到的是通过 SSL 模拟 RPC 应用程序与其服务器的通信,例如,使用curl
. 为此,我需要获取应用程序网络流量的详细日志。
采纳答案by GreyFairer
Can't you use a logging proxy server, e.g. http://www.charlesproxy.com/or http://fiddler2.com/? Charles Proxy can also decode AMF requests, Fiddler is the champion for SSL interception.
您不能使用日志代理服务器,例如http://www.charlesproxy.com/或http://fiddler2.com/吗?Charles Proxy 也可以解码 AMF 请求,Fiddler 是 SSL 拦截的冠军。
IIRC you can set system properties http.proxyHost and http.proxyPort to 127.0.0.1 and 8888, and java URLConnections will automatically connect via your logging proxy server, and you get a nice view of your HTTP Traffic.
IIRC 您可以将系统属性 http.proxyHost 和 http.proxyPort 设置为 127.0.0.1 和 8888,并且 java URLConnections 将通过您的日志代理服务器自动连接,您可以很好地查看 HTTP 流量。
Or, if the intention is to be able to replay the communication, use JMeter HTTP Proxy, this records in a format that is suitable for replay. It has also built-in support for handling cookies.
或者,如果目的是能够重放通信,请使用 JMeter HTTP 代理,以适合重放的格式记录。它还内置了处理 cookie 的支持。
If the application uses nice web services, SoapUI also has a monitoring proxy that intercepts web service calls for which you have imported the WSDL.
如果应用程序使用了不错的 Web 服务,SoapUI 也有一个监视代理来拦截您导入 WSDL 的 Web 服务调用。
回答by giampaolo
I just want to post a snippet of code that you can use at starting point. I do not have a"global" logger but with small changes to existing code you can reach your goal. I "log" on standard output, since your problem can be split into two pieces: getting the info from UrlConnection and store it for further reference.
我只想发布您可以在起点使用的代码片段。我没有“全局”记录器,但是对现有代码进行一些小的更改就可以实现您的目标。我在标准输出上“登录”,因为您的问题可以分为两部分:从 UrlConnection 获取信息并将其存储以供进一步参考。
This code logs the request:
此代码记录请求:
public class URLConnectionReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("http://www.google.com/");
URLConnection yc = oracle.openConnection();
String headerName = null;
for (int i = 1; (headerName = yc.getHeaderFieldKey(i)) != null; i++) {
if (headerName.equals("Set-Cookie")) {
String cookie = yc.getHeaderField(i);
System.out.println("Cookie :: " + cookie);
} else {
System.out.println("Header: "+ yc.getHeaderField(i));
}
}
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
}
saving all this data to one or more files is not hard. If you believe that I'm on right way for you problem, I would be glad to edit the answer with other details as needed.
将所有这些数据保存到一个或多个文件并不难。如果您认为我对您的问题是正确的,我很乐意根据需要使用其他详细信息编辑答案。
回答by GreyFairer
I dug a little further, and apparently, HttpURLConnection comes with java.util.logging enabled by default.
我进一步挖掘了一点,显然 HttpURLConnection 默认启用了 java.util.logging。
See related questions: Java: Display request of an HttpURLConnection before sendingand How to enable wire logging for a java HttpURLConnection traffic?
请参阅相关问题: Java:在发送之前显示 HttpURLConnection 的请求以及如何为 java HttpURLConnection 流量启用线路日志记录?
Java.util.logging was Sun's (failed) attempt at standardizing logging providers in Java 1.4. You can bridge it to SLF4J via the jul-to-slf4j module if you want to avoid tweaking system properties.
Java.util.logging 是 Sun 在 Java 1.4 中标准化日志记录提供程序的(失败)尝试。如果您想避免调整系统属性,您可以通过 jul-to-slf4j 模块将其桥接到 SLF4J。
But I would still prefer Fiddler or JMeter proxy though :-)
但我仍然更喜欢 Fiddler 或 JMeter 代理:-)
回答by Ehsan Khodarahmi
If you want to log network traffic & you have URLConnection objects then the problem is already solved!
If you want to log at stream level, you need to write a little wrapper on top of your I/O streams & log all data before transfer them to lower network layers, otherwise you can use connection objects directly to get required info & log them.
For managing cookies, you should use java.net.HttpCookie
which is introduced in java 6. Only thing you have to do is to create an instance of CookieManager & set it as default cookie manager:
如果你想记录网络流量并且你有 URLConnection 对象,那么问题已经解决了!
如果要在流级别进行日志记录,则需要在 I/O 流之上编写一个小包装器并记录所有数据,然后再将它们传输到较低的网络层,否则您可以直接使用连接对象来获取所需信息并记录它们.
要管理 cookie,您应该使用java.net.HttpCookie
java 6 中引入的 which。您唯一要做的就是创建一个 CookieManager 实例并将其设置为默认 cookie 管理器:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
& you can use it for managing connection cookies!
& 您可以使用它来管理连接 cookie!
回答by Julius Musseau
A quick way to log all SSL traffic is to startup java with:
记录所有 SSL 流量的一种快速方法是使用以下命令启动 java:
-Djavax.net.debug=all
Or set it as a system property:
或将其设置为系统属性:
System.setProperty("javax.net.debug","all");
Brace yourself. Standard out gets NOISY if you do this!
振作起来。如果你这样做,标准输出会变得嘈杂!
(*Note: only logs SSL traffic and SSL debug info (handshakes, etc). Regular sockets are not logged.)
(*注意:仅记录 SSL 流量和 SSL 调试信息(握手等)。不记录常规套接字。)