Java 获取将从HttpPost发送的完整原始HTTP请求消息
我正在尝试构建一个原始HTTP POST请求。但是,我不想实际连接到服务器并发送消息 我一直在浏览ApacheHTTP库,希望我可以创建一个HttpPost对象,设置实体,然后获取它本来会创建的消息。到目前为止,我可以转储实体,但不能像服务器端那样转储整个请求 有什么想法吗?当然,除了重新创建轮子之外 解决方案 我将ShyJ的响应重构为一对静态类,但是原始响应工作得很好。以下是两个类:Java 获取将从HttpPost发送的完整原始HTTP请求消息,java,apache,http,post,Java,Apache,Http,Post,我正在尝试构建一个原始HTTP POST请求。但是,我不想实际连接到服务器并发送消息 我一直在浏览ApacheHTTP库,希望我可以创建一个HttpPost对象,设置实体,然后获取它本来会创建的消息。到目前为止,我可以转储实体,但不能像服务器端那样转储整个请求 有什么想法吗?当然,除了重新创建轮子之外 解决方案 我将ShyJ的响应重构为一对静态类,但是原始响应工作得很好。以下是两个类: public static final class LoopbackPostMethod extends Po
public static final class LoopbackPostMethod extends PostMethod {
private static final String STATUS_LINE = "HTTP/1.1 200 OK";
@Override
protected void readResponse(HttpState state, HttpConnection conn) throws IOException, HttpException {
statusLine = new StatusLine (STATUS_LINE);
}
}
public static final class LoopbackHttpConnection extends HttpConnection {
private static final String HOST = "127.0.0.1";
private static final int PORT = 80;
private final OutputStream fOutputStream;
public LoopbackHttpConnection(OutputStream outputStream) {
super(HOST, PORT);
fOutputStream = outputStream;
}
@Override
public void flushRequestOutputStream() throws IOException { /* do nothing */ }
@Override
public OutputStream getRequestOutputStream() throws IOException, IllegalStateException {
return fOutputStream;
}
@Override
public void write(byte[] data) throws IOException, IllegalStateException {
fOutputStream.write(data);
}
}
以下是我在自己的实现中使用的工厂方法,作为示例:
private ByteBuffer createHttpRequest(ByteBuffer data) throws HttpException, IOException {
LoopbackPostMethod postMethod = new LoopbackPostMethod();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
postMethod.setRequestEntity(new ByteArrayRequestEntity(data.array()));
postMethod.execute(new HttpState(), new LoopbackHttpConnection(outputStream));
byte[] bytes = outputStream.toByteArray();
ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
buffer.put(bytes);
return buffer;
}
我要做的是实现一个或多个HttpClient接口,并使用我的no-op实现 例如,查看
ClientConnectionManager
和AbstractHttpClient
。任何连接。这可以通过使用和伪造一些方法来实现。我使用了http客户端的3.1
版本
范例
此代码:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.StatusLine;
import org.apache.commons.httpclient.methods.PostMethod;
public class Main {
public static void main(String[] args) throws Exception {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
PostMethod method = new PostMethod () {
@Override
protected void readResponse(HttpState state, HttpConnection conn)
throws IOException, HttpException {
statusLine = new StatusLine ("HTTP/1.1 200 OK");
}
};
method.addParameter("aa", "b");
method.execute(new HttpState (), new HttpConnection("http://www.google.abc/hi", 80) {
@Override
public void flushRequestOutputStream() throws IOException {
}
@Override
public OutputStream getRequestOutputStream() throws IOException,
IllegalStateException {
return baos;
}
@Override
public void write(byte[] data) throws IOException,
IllegalStateException {
baos.write(data);
}
});
final String postBody = new String (baos.toByteArray());
System.out.println(postBody);
}
}
会回来的
POST / HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.1
Host: http://www.google.abc/hi
Content-Length: 4
Content-Type: application/x-www-form-urlencoded
aa=b
使用HttpClient 4.x
private static String toRawHttp(HttpUriRequest request) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
HttpTransportMetricsImpl outTransportMetrics = new HttpTransportMetricsImpl();
SessionOutputBufferImpl buffer = new SessionOutputBufferImpl(outTransportMetrics, 1);
HttpMessageWriter<HttpRequest> defaultHttpRequestWriter = DefaultHttpRequestWriterFactory.INSTANCE.create(buffer);
DefaultHttpRequestWriterFactory writerFactory = new DefaultHttpRequestWriterFactory(null) {
@Override
public HttpMessageWriter<HttpRequest> create(SessionOutputBuffer buffer) {
return defaultHttpRequestWriter;
}
};
buffer.bind(baos);
ConnectionConfig config = ConnectionConfig.DEFAULT;
DefaultBHttpClientConnection connection = new DefaultBHttpClientConnection(config.getBufferSize(),
config.getFragmentSizeHint(),
ConnSupport.createDecoder(config),
ConnSupport.createEncoder(config),
config.getMessageConstraints(),
null,
null,
writerFactory,
null) {
@Override
protected void ensureOpen() {
//using writerFactory buffer instead of socket
}
@Override
protected OutputStream createOutputStream(long len, SessionOutputBuffer outbuffer) {
if (len == ContentLengthStrategy.CHUNKED) {
return new ChunkedOutputStream(2048, buffer);
} else if (len == ContentLengthStrategy.IDENTITY) {
return new IdentityOutputStream(buffer);
} else {
return new ContentLengthOutputStream(buffer, len);
}
}
};
CloseableHttpClient client = HttpClients.custom()
.setRequestExecutor(new HttpRequestExecutor() {
@Override
protected HttpResponse doSendRequest(HttpRequest request, HttpClientConnection conn, HttpContext context) throws IOException, HttpException {
// inject fake connection
return super.doSendRequest(request, connection, context);
}
@Override
protected HttpResponse doReceiveResponse(HttpRequest request, HttpClientConnection conn, HttpContext context) {
return new BasicHttpResponse(request.getProtocolVersion(), 200, "OK");
}
})
.build();
client.execute(request);
return new String(baos.toByteArray());
}
将打印:
POST /ff HTTP/1.1
X-Hello: Word
Host: localhost:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.8 (Java/1.8.0_161)
Accept-Encoding: gzip,deflate
POST /ff HTTP/1.1
X-Hello: Word
Host: localhost:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.8 (Java/1.8.0_161)
Accept-Encoding: gzip,deflate