Apache HTTP/2 客户端 5.0 POST 请求丢失 payload/content
Apache HTTP/2 Client 5.0 POST request missing payload/content
我将一个小型示例 servlet 部署到 Tomcat,它将回显任何接收到的参数。 Tomcat 配置为支持 HTTP/1.1 和 HTTP/2。我可以使用 curl
向 servlet 发出 GET 请求,证明它在 HTTP/1.1 和 HTTP/2.
上都有效
使用 Apache HTTP 5.0 客户端我有一个单元测试来命中 servlet 和 POST
一个带有一些参数(请求内容)的请求工作正常 - 服务器接收参数并且 returns他们回到客户那里我可以阅读它们。在此测试中,我调用客户端使用 HTTP/1.1 或 HTTP/2 使用 CloseableHttpAsyncClient.setVersionPolicy()
调用。但是,如果我改为使用 HTTP/2 那么客户端不会向服务器发送请求内容。
下面是成功调用 HTTP/1.1 的示例代码 - 您可以看到我有 setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
。如果我将其更改为 FORCE_HTTP_2
,则会通过 HTTP/2.0 进行调用,但不会发送请求内容。
任何人都可以建议我做错了什么或我需要做些什么吗?我没有找到很多关于使用新的 Apache 5.0 客户端库的文档,并且示例没有显示发送和 POST 内容(或者至少是我能找到的内容)。
public void testWithHTTP1() throws Exception {
final String content = "Code=99&Message=Hello";
final String contentType = "application/text";
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
.build();
client.start();
final HttpHost target = new HttpHost("http","localhost",8002);
final String requestUri = "/VSFTestMT_Test/Test/Test_EchoHttpGet";
final HttpClientContext clientContext = HttpClientContext.create();
final SimpleHttpRequest httppost = SimpleHttpRequests.post(target, requestUri);
httppost.setBody(content, ContentType.create("application.x_www_form_urlencoded"));
final Future<SimpleHttpResponse> future = client.execute(
httppost,
clientContext,
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
System.out.println(requestUri + "->" + response.getCode());
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
System.out.println(requestUri + "->" + ex);
}
@Override
public void cancelled() {
System.out.println(requestUri + " cancelled");
}
});
System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);
}
看起来他们有一个完全不同的构建器 Http/2 查看他们的源代码:
/**
* Creates builder object for construction of custom HTTP/2
* {@link CloseableHttpAsyncClient} instances optimized for HTTP/2 protocol
* and message multiplexing
*/
public static H2AsyncClientBuilder customHttp2() {
return H2AsyncClientBuilder.create();
}
/**
* Creates HTTP/2 {@link CloseableHttpAsyncClient} instance with default configuration and
* system properties optimized for HTTP/2 protocol and message multiplexing.
*/
public static CloseableHttpAsyncClient createHttp2System() {
return H2AsyncClientBuilder.create().useSystemProperties().build();
}
因此我建议您尝试实际的 customHttp2(),而不是 custom()。
HTTP/1 可以通过 HTTP 和 HTTPS 实现,但是 HTTP/2 只能在 HTTPS 中实现。
据我所知,您只调用了 http url,这可能是 servlet 无法获取负载内容的原因
请多看这个detail
我将一个小型示例 servlet 部署到 Tomcat,它将回显任何接收到的参数。 Tomcat 配置为支持 HTTP/1.1 和 HTTP/2。我可以使用 curl
向 servlet 发出 GET 请求,证明它在 HTTP/1.1 和 HTTP/2.
使用 Apache HTTP 5.0 客户端我有一个单元测试来命中 servlet 和 POST
一个带有一些参数(请求内容)的请求工作正常 - 服务器接收参数并且 returns他们回到客户那里我可以阅读它们。在此测试中,我调用客户端使用 HTTP/1.1 或 HTTP/2 使用 CloseableHttpAsyncClient.setVersionPolicy()
调用。但是,如果我改为使用 HTTP/2 那么客户端不会向服务器发送请求内容。
下面是成功调用 HTTP/1.1 的示例代码 - 您可以看到我有 setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
。如果我将其更改为 FORCE_HTTP_2
,则会通过 HTTP/2.0 进行调用,但不会发送请求内容。
任何人都可以建议我做错了什么或我需要做些什么吗?我没有找到很多关于使用新的 Apache 5.0 客户端库的文档,并且示例没有显示发送和 POST 内容(或者至少是我能找到的内容)。
public void testWithHTTP1() throws Exception {
final String content = "Code=99&Message=Hello";
final String contentType = "application/text";
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
.build();
client.start();
final HttpHost target = new HttpHost("http","localhost",8002);
final String requestUri = "/VSFTestMT_Test/Test/Test_EchoHttpGet";
final HttpClientContext clientContext = HttpClientContext.create();
final SimpleHttpRequest httppost = SimpleHttpRequests.post(target, requestUri);
httppost.setBody(content, ContentType.create("application.x_www_form_urlencoded"));
final Future<SimpleHttpResponse> future = client.execute(
httppost,
clientContext,
new FutureCallback<SimpleHttpResponse>() {
@Override
public void completed(final SimpleHttpResponse response) {
System.out.println(requestUri + "->" + response.getCode());
System.out.println(response.getBody());
}
@Override
public void failed(final Exception ex) {
System.out.println(requestUri + "->" + ex);
}
@Override
public void cancelled() {
System.out.println(requestUri + " cancelled");
}
});
System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);
}
看起来他们有一个完全不同的构建器 Http/2 查看他们的源代码:
/**
* Creates builder object for construction of custom HTTP/2
* {@link CloseableHttpAsyncClient} instances optimized for HTTP/2 protocol
* and message multiplexing
*/
public static H2AsyncClientBuilder customHttp2() {
return H2AsyncClientBuilder.create();
}
/**
* Creates HTTP/2 {@link CloseableHttpAsyncClient} instance with default configuration and
* system properties optimized for HTTP/2 protocol and message multiplexing.
*/
public static CloseableHttpAsyncClient createHttp2System() {
return H2AsyncClientBuilder.create().useSystemProperties().build();
}
因此我建议您尝试实际的 customHttp2(),而不是 custom()。
HTTP/1 可以通过 HTTP 和 HTTPS 实现,但是 HTTP/2 只能在 HTTPS 中实现。
据我所知,您只调用了 http url,这可能是 servlet 无法获取负载内容的原因
请多看这个detail