记录Java应用程序的所有网络交互

时间:2013-08-29 13:36:20

标签: java debugging rpc

我有一个怪异的Java应用程序(鲜为人知的应用程序服务器GNUEnterprise的客户端)及其源代码,我可以在对其进行一些更改后编译回来。该应用程序大量使用网络,我需要监控每个请求和响应。我可以使用像Wireshark这样的嗅探器,但该应用程序可以通过SSL使用其服务器,因此不知道SSL证书的私钥任何嗅探流量都是无用的。

如何从应用程序本身记录每个请求和响应,我该怎么办?我需要查看所有已发送和已接收的标头。我不想改变负责网络交互的所有代码。我想要的是像

这样的代码
Network.setDefaultLogger(myCustomLoggerInstance);

在应用程序启动附近,然后在myCustomLoggerInstance执行我需要的所有日志记录。

此外,鉴于所有网络操作都是使用URLConnection进行的,我可以使用con.getHeaderFields()获取响应标头,并使用con.getRequestProperties()获取请求标头。但为什么饼干不存在?如何以相同的方式转储发送和接收的cookie?

编辑:我想要达到的目的是模仿RPC应用程序与SSL服务器之间的通信,例如使用curl。为此,我需要获取应用程序网络流量的详细日志。

5 个答案:

答案 0 :(得分:15)

您不能使用日志记录代理服务器,例如http://www.charlesproxy.com/http://fiddler2.com/? Charles Proxy也可以解码AMF请求,Fiddler是SSL拦截的拥护者。

IIRC你可以将系统属性http.proxyHost和http.proxyPort设置为127.0.0.1和8888,java URLConnections将通过你的日志代理服务器自动连接,你可以很好地查看你的HTTP流量。

或者,如果打算重播通信,请使用JMeter HTTP Proxy,它以适合重播的格式记录。它还内置了对cookie的处理支持。

如果应用程序使用了不错的Web服务,SoapUI还有一个监视代理,它拦截您为其导入WSDL的Web服务调用。

答案 1 :(得分:13)

记录所有SSL流量的快速方法是使用以下命令启动java:

-Djavax.net.debug=all

或者将其设置为系统属性:

System.setProperty("javax.net.debug","all");

支撑自己。如果你这样做,标准输出就会变成NOISY!

(*注意:仅记录SSL流量和SSL调试信息(握手等)。不记录常规套接字。)

答案 2 :(得分:2)

我只想发布一个你可以在起点使用的代码片段。我没有“全局”记录器,但对现有代码进行少量更改,您可以实现目标。我在标准输出上“登录”,因为您的问题可以分为两部分:从UrlConnection获取信息并存储以供进一步参考。

此代码记录请求:

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();
}

}

将所有这些数据保存到一个或多个文件并不难。如果您认为我正确处理您的问题,我很乐意根据需要编辑其他详细信息。

答案 3 :(得分:2)

我进一步挖了一下,显然,HttpURLConnection默认启用了java.util.logging。

查看相关问题: Java: Display request of an HttpURLConnection before sendingHow to enable wire logging for a java HttpURLConnection traffic?

Java.util.logging是Sun在Java 1.4中标准化日志记录提供程序的尝试(失败)。如果要避免调整系统属性,可以通过jul-to-slf4j模块将其桥接到SLF4J。

但我仍然更喜欢Fiddler或JMeter代理: - )

答案 4 :(得分:1)

如果您想记录网络流量&你有URLConnection对象然后问题已经解决了!
如果要以流级别进行日志记录,则需要在I / O流和数据流之上编写一个小包装器。在将所有数据传输到较低网络层之前记录所有数据,否则您可以直接使用连接对象来获取所需信息&记录它们。
对于管理cookie,您应该使用java 6中引入的java.net.HttpCookie。您唯一需要做的就是创建一个CookieManager&的实例。将其设置为默认cookie管理器:

CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

&安培;你可以用它来管理连接cookie!