を有効にする方法については、ワイヤーロギングのためのjava HttpURLConnectionの交通?
-
22-07-2019 - |
質問
に使用しました ジャカルタ-コモンズHttpClient 他のプロジェクトという同 ワイヤーロギング 出力で、"標準"HttpUrlConnectionの
に使用しました フィドラーズ プロキシとしていつづけたいと思っていますログインにより、交通から直接java.
撮影に合うワインの接続により入力と出力ストリームが足りないので、HTTPヘッダを書いたり消費量のHttpUrlConnectionのクラスとがあるかどうか分かりませんがログインできなくなり、ツールを提供します。
解決 2
ていたんログインできるようすべてのSSL交通の実施に自分の SSLSocketFactory のデフォルトです。
このため当社の全ての接続はHTTPSを使用し設定可能で、ソケット工場の方法 HttpsURLConnection.setSSLSocketFactory.
より完全ソリューションのモニタリングを可能とするすべてのソケットです http://www.javaspecialists.eu/archive/Issue169.html 感謝 ローレンスDol ポインティングの使用 ソケットが開かれます。setSocketImplFactory
ここでは私の準備が出来ていないため生産コード:
public class WireLogSSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory delegate;
public WireLogSSLSocketFactory(SSLSocketFactory sf0) {
this.delegate = sf0;
}
public Socket createSocket(Socket s, String host, int port,
boolean autoClose) throws IOException {
return new WireLogSocket((SSLSocket) delegate.createSocket(s, host, port, autoClose));
}
/*
...
*/
private static class WireLogSocket extends SSLSocket {
private SSLSocket delegate;
public WireLogSocket(SSLSocket s) {
this.delegate = s;
}
public OutputStream getOutputStream() throws IOException {
return new LoggingOutputStream(delegate.getOutputStream());
}
/*
...
*/
private static class LoggingOutputStream extends FilterOutputStream {
private static final Logger logger = Logger.getLogger(WireLogSocket.LoggingOutputStream.class);
//I'm using a fixed charset because my app always uses the same.
private static final String CHARSET = "ISO-8859-1";
private StringBuffer sb = new StringBuffer();
public LoggingOutputStream(OutputStream out) {
super(out);
}
public void write(byte[] b, int off, int len)
throws IOException {
sb.append(new String(b, off, len, CHARSET));
logger.info("\n" + sb.toString());
out.write(b, off, len);
}
public void write(int b) throws IOException {
sb.append(b);
logger.info("\n" + sb.toString());
out.write(b);
}
public void close() throws IOException {
logger.info("\n" + sb.toString());
super.close();
}
}
}
}
他のヒント
SunのHttpURLConnectionソース JUL 。
セットアップ(必要に応じてパスを調整):
-Djava.util.logging.config.file=/full/path/to/logging.properties
logging.properties:
handlers= java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = FINEST
sun.net.www.protocol.http.HttpURLConnection.level=ALL
これはコンソールにログを記録し、必要に応じて調整します。ファイルに記録します。
出力例:
2010-08-07 00:00:31 sun.net.www.protocol.http.HttpURLConnection writeRequests
FIN: sun.net.www.MessageHeader@16caf435 pairs: {GET /howto.html HTTP/1.1: null}{User-Agent: Java/1.6.0_20}{Host: www.rgagnon.com}{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}{Connection: keep-alive}
2010-08-07 00:00:31 sun.net.www.protocol.http.HttpURLConnection getInputStream
FIN: sun.net.www.MessageHeader@5ac0728 pairs: {null: HTTP/1.1 200 OK}{Date: Sat, 07 Aug 2010 04:00:33 GMT}{Server: Apache}{Accept-Ranges: bytes}{Content-Length: 17912}{Keep-Alive: timeout=5, max=64}{Connection: Keep-Alive}{Content-Type: text/html}
これは本文のないヘッダーのみを印刷することに注意してください。
http://www.rgagnon.com/javadetails/javaを参照-debug-HttpURLConnection-problem.html で詳細を確認してください。
システムプロパティ -Djavax.net.debug = all
もあります。ただし、主に SSLデバッグに役立ちます 。
解決策1:デコレータパターンを使用する
また、必ず親クラス URLConnection.getOutputStream(): OutputStream および URLConnection.html#getInputStream(): InputStream メソッドは装飾されたを返しますOutputStream および InputStream オブジェクトも同様です。
。
解決策2:カスタムのインメモリHTTPプロキシを使用する
単純なhttpプロキシサーバーを作成し、アプリケーションの起動と初期化中に別のスレッドで起動するようにします。 単純なプロキシサーバーの例を参照してください。
すべてのリクエストに対して上記のHTTPプロキシを使用するようにアプリケーションを構成します。 プロキシを使用するためのJavaの構成を参照してください。
すべてのトラフィックは、フィドラーで発生するのと同じように、プロキシを通過します。したがって、未加工のhttpストリームにアクセスできます"クライアントからサーバー"および「サーバーからクライアントに戻る」。この生の情報を解釈し、必要に応じてログに記録する必要があります。
更新: SSLベースのWebサーバーへのアダプターとしてHTTPプロキシを使用します。
== Client System ===============================
| |
| ------------------------------ |
| | | |
| | Java process | |
| | ---- | |
| | ---------- | | | |
| | | | -O | | |
| | | Logging | | | |
| | | Proxy <---HTTP-- | ----- |
| | | Adapter | | | | |
| | | Thread o------------------> | |
| | | o | | | | |
| | --------|- | | Log | |
| | | | ----- |
| ----------------|------------- |
| | |
=====================|==========================
|
|
HTTPS
SSL
|
== Server System ====|==========================
| | |
| ----------------|---------------- |
| | V | |
| | | |
| | Web Server | |
| | | |
| --------------------------------- |
| |
================================================
Linuxでは、straceでVMを実行できます:
strace -o strace.out -s 4096 -e trace = network -f java ...
自動的に行うことはできないと思いますが、 FilterOutputStream および FilterInputStream に HttpUrlConnection
の出力および入力ストリームをパラメーターとして指定します。次に、バイトの書き込み/読み取りが行われたら、それらをログに記録するとともに、それらを基礎となるストリームに渡します。
AspectJを使用してPointcutを挿入し、メソッドの周りにロギングアドバイスを追加するのはどうですか? AspectJはプライベート/保護されたメソッドに組み込むことができると思います。
sun.net.www.protocol.http.HttpURLConnection.writeRequestはsun.net.www.http.HttpClient.writeRequestを呼び出して、MessageHeaderオブジェクトを入力として受け取り、それがターゲットになるようです。
最終的にはこれは機能する可能性がありますが、非常に壊れやすく、Sun JVMでのみ機能します。実際に使用しているのは正確なバージョンのみです。
ワイヤー上のコンテンツ(ヘッダー、本文など)にのみ興味があるという偶然の機会に、 wireshark を試してください。
これには、コードを変更する必要がないという利点がありますが、コードを介してログを有効にすることが目的であれば、この回答は適用されません。
Java 8環境で更新するには:
@sleskeの回答をフォロー
System.setProperty("javax.net.debug","all");
箱から出してすぐに私のために働いた。
また、@ weberjnの提案
strace -o strace.out -s 4096 -e trace=network -f java
ただし、エンコードされたストリームをダンプするため、SSLトラフィックで処理する場合は役立ちません。
他のすべてのコードトリックはうまくいきませんでしたが、おそらく十分に努力していませんでした。