一尘不染

如何启用Java HttpURLConnection通信的有线日志记录?

java

我在另一个项目中使用了雅加达公用HttpClient,我希望使用相同的线路记录输出,但是使用“标准”
HttpUrlConnection。

我已经使用Fiddler作为代理,但是我想直接从Java记录流量。

捕获连接输入和输出流的内容还不够,因为HTTP标头是由HttpUrlConnection类编写和使用的,因此我将无法记录标头。


阅读 241

收藏
2020-09-08

共1个答案

一尘不染

我已经能够记录所有SSL流量,并在默认端口之上实现自己的SSLSocketFactory

这对我有用,因为我们所有的连接都使用HTTPS,并且可以使用HttpsURLConnection.setSSLSocketFactory方法设置套接字工厂。

可以在http://www.javaspecialists.eu/archive/Issue169.html上找到支持所有套接字的更完整解决方案
感谢Lawrence
Dol
指出了使用Socket.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();
            }
        }
    }
}
2020-09-08