我在另一个项目中使用了雅加达公用HttpClient,我希望使用相同的线路记录输出,但是使用“标准” HttpUrlConnection。
我已经使用Fiddler作为代理,但是我想直接从Java记录流量。
捕获连接输入和输出流的内容还不够,因为HTTP标头是由HttpUrlConnection类编写和使用的,因此我将无法记录标头。
我已经能够记录所有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(); } } } }