Apache或其他客户端Java实现是否支持HTTP/2?

12

我正在寻找一个能够连接到基于HTTP/2的服务器的Java客户端。该服务器已经支持HTTP/2 API。我没有看到最受欢迎的Apache Http客户端https://hc.apache.org/仍然支持HTTP/2。

Apache是否已经有了支持Http/2的Java客户端实现?

如果没有,是否有一些Java客户端可以支持连接到HTTP/2,最好是在Java 7上?

4个回答

8

Jetty提供了两个HTTP/2 Java客户端API。这两个API都需要Java 8或更高版本,并且必须使用ALPN,如此处所述。

低级别API

这些API基于HTTP2Client,它基于HTTP/2的会话概念,并使用监听器来通知从服务器接收到的HTTP/2

    // Setup and start the HTTP2Client.
    HTTP2Client client = new HTTP2Client();
    SslContextFactory sslContextFactory = new SslContextFactory();
    client.addBean(sslContextFactory);
    client.start();

    // Connect to the remote host to obtains a Session.
    FuturePromise<Session> sessionPromise = new FuturePromise<>();
    client.connect(sslContextFactory, new InetSocketAddress(host, port), new ServerSessionListener.Adapter(), sessionPromise);
    Session session = sessionPromise.get(5, TimeUnit.SECONDS);

    // Use the session to make requests.
    HttpFields requestFields = new HttpFields();
    requestFields.put("User-Agent", client.getClass().getName() + "/" + Jetty.VERSION);
    MetaData.Request metaData = new MetaData.Request("GET", new HttpURI("https://webtide.com/"), HttpVersion.HTTP_2, requestFields);
    HeadersFrame headersFrame = new HeadersFrame(metaData, null, true);
    session.newStream(headersFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter()
    {
        @Override
        public void onHeaders(Stream stream, HeadersFrame frame)
        {
            // Response headers.
            System.err.println(frame);
        }

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback)
        {
            // Response content.
            System.err.println(frame);
            callback.succeeded();
        }
    });

高级API

Jetty的HttpClient提供了一种使用不同传输方式的方法,其中之一是HTTP/2传输方式。应用程序将使用更高级别的HTTP API,但在Jetty下面,将使用HTTP/2来传输HTTP语义。

这样,应用程序可以透明地使用HttpClient提供的高级API,并在配置或启动代码中分离出要使用的传输方式。

    // Setup and start HttpClient with HTTP/2 transport.
    HTTP2Client http2Client = new HTTP2Client();
    SslContextFactory sslContextFactory = new SslContextFactory();
    HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP2(http2Client), sslContextFactory);
    httpClient.start();

    // Make a request.
    ContentResponse response = httpClient.GET("https://webtide.com/");

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Neeraj Krishna
我忘了提到ALPN要求。我已经更新了答案,并附上了ALPN文档部分的链接。 - sbordet
我最终选择了Netty,因为它不需要ALPN支持。 - Neeraj Krishna

3

这里有一个与Android和Java应用程序相关的HTTP和HTTP/2客户端:OkHttp


2

Jetty从9.3版本开始支持HTTP2。这包括服务器和客户端


0

Apache httpclient-5 beta支持从jdk9或以上版本开始使用http/2

例如:

public static void main(final String[] args) throws Exception {
    final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustAllStrategy()).build();
    final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create().setTlsStrategy(new H2TlsStrategy(sslContext, NoopHostnameVerifier.INSTANCE)).build();
    final IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setSoTimeout(Timeout.ofSeconds(5)).build();
    final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, null, ioReactorConfig, connectionManager);

    client.start();
    final HttpHost target = new HttpHost("localhost", 8082, "https");
    final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
    final AsyncClientEndpoint endpoint = leaseFuture.get(10, TimeUnit.SECONDS);
    try {
        String[] requestUris = new String[] {"/"};
        CountDownLatch latch = new CountDownLatch(requestUris.length);
        for (final String requestUri: requestUris) {
            SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
            endpoint.execute(SimpleRequestProducer.create(request), SimpleResponseConsumer.create(), new FutureCallback<SimpleHttpResponse>() {
                    @Override
                    public void completed(final SimpleHttpResponse response) {
                        latch.countDown();
                        System.out.println(requestUri + "->" + response.getCode());
                        System.out.println(response.getBody());
                    }

                    @Override
                    public void failed(final Exception ex) {
                        latch.countDown();
                        System.out.println(requestUri + "->" + ex);
                        ex.printStackTrace();
                    }

                    @Override
                    public void cancelled() {
                        latch.countDown();
                        System.out.println(requestUri + " cancelled");
                    }

                });
        }
        latch.await();
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        endpoint.releaseAndReuse();
    }

    client.shutdown(ShutdownType.GRACEFUL);
}

参考: https://hc.apache.org/httpcomponents-client-5.0.x/examples-async.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接