java - 获取从 HttpGet 发送的原始 HTTP 请求消息?

标签 java apache-commons-httpclient apache-httpcomponents

如何在 Apache http 组件 v4.3.5 中获取完整的原始 HTTP 请求消息。 我设法只得到解析后的响应。

public String get(String uri) {
    try (CloseableHttpClient httpclient = HttpClients.createDefault(); CloseableHttpResponse response1 = httpclient.execute(new HttpGet(uri))) {
        HttpEntity entity = response1.getEntity();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        entity.writeTo(byteArrayOutputStream);
        return new String(byteArrayOutputStream.toByteArray());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

还有类似的answer but for the old 3.1 version of apache commons-http v3.1 。 v4.3.5 如何操作?

最佳答案

就这样工作了。不是最优雅,因为流被复制到内存,但适用于我的用例。

public class TestHttpClient {
    public String get(String uri) {
        StreamRecorder streamRecorder = new StreamRecorder();
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new ListeningSocketFactory(streamRecorder))
                .register("https", SSLConnectionSocketFactory.getSocketFactory())
                .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        try (CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connManager).build(); CloseableHttpResponse response1 = httpclient.execute(new HttpGet(uri))) {
            HttpEntity entity = response1.getEntity();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            entity.writeTo(byteArrayOutputStream);
            return new String(streamRecorder.getRecordedStreamAsCharArray());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String s = new TestHttpClient().get("http://onet.pl");
        System.out.println("---------------------\n" +
                "RESULT:\n" +
                "---------------------" +
                "\n" + s.substring(0, Math.min(s.length(), 200)));
    }
}

public class ListeningSocketFactory extends PlainConnectionSocketFactory {
    private final CopyInputStream.InputStreamListener streamListener;

    public ListeningSocketFactory(StreamRecorder streamListener) {
        this.streamListener = streamListener;
    }

    @Override
    public Socket createSocket(HttpContext context) throws IOException {
        return new SocketWithInputStreamListener(streamListener);
    }

}

class StreamRecorder implements CopyInputStream.InputStreamListener {
    private final List<Integer> streamCopy = new ArrayList<>(1000);

    @Override
    public synchronized void processByte(int readByte) {
        streamCopy.add(readByte);
    }

    public synchronized char[] getRecordedStreamAsCharArray() {
        char[] result = new char[streamCopy.size()];
        for (int i = 0; i < streamCopy.size(); i++) {
            result[i] = (char) i;
        }
        return result;
    }
}


public class CopyInputStream extends FilterInputStream {
    private final InputStreamListener streamListener;

    CopyInputStream(InputStream in, InputStreamListener streamListener) {
        super(in);
        this.streamListener = streamListener;
    }

    @Override
    public int read() throws IOException {
        int readByte = super.read();
        processByte(readByte);
        return readByte;
    }

    @Override
    public int read(byte[] buffer, int offset, int count) throws IOException {
        int readBytes = super.read(buffer, offset, count);
        processBytes(buffer, offset, readBytes);
        return readBytes;
    }

    private void processBytes(byte[] buffer, int offset, int readBytes) {
        for (int i = 0; i < readBytes; i++) {
            processByte(buffer[i + offset]);
        }
    }

    private void processByte(int readByte) {
        streamListener.processByte(readByte);
    }

    interface InputStreamListener {
        void processByte(int readByte);
    }
}

关于java - 获取从 HttpGet 发送的原始 HTTP 请求消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25242190/

相关文章:

java - 如何查看点击了哪个通知ID?

java - 如何使用Java将字符串发送到服务器?

ssl - 使用 ProxySelector 的 Jax-WS Axis2 Proxy over SSL 错误

java - 如何将 org.apache.http.legacy 添加到 sbt 中

java - 在 Java 中处理下载

java - 已弃用 HttpGet、HttpClient、HttpResponse、HttpEntity、EntityUtils

apache-camel - Camel Exchange getbody 的文件对象为空

java - 如何与 webdriver 中的 List<WebElement> 进行比较?

java - Jboss 6.0 中 OpenJPA 的 ClassCastException

java - 在 ControllerAdvice 之前捕获反序列化异常