Java 通过JAX-RS客户端支持HTTP/1.1和HTTP/2

Java 通过JAX-RS客户端支持HTTP/1.1和HTTP/2,java,http,jersey,jetty,http2,Java,Http,Jersey,Jetty,Http2,我想实现一个JAX-RS客户机,它支持JAX-RS客户机的HTTP/1.1和HTTP/2 如果服务器支持带有HTTP/2的ALPN,则使用HTTP/2;如果服务器不提供任何信息,则使用HTTP/1.1 我读过一些关于ALPN的文章,这似乎是可能的,但我没有发现任何东西同时支持这些协议。我没能把它们插在一起 我目前正在使用和。解决方案可以是使用nginx(或apache2)作为反向代理来处理该需求 Nginx可以将jetty服务器(仅使用http/1.1或http/2协议)和带有alpn的服务器h

我想实现一个JAX-RS客户机,它支持JAX-RS客户机的HTTP/1.1和HTTP/2

如果服务器支持带有HTTP/2的ALPN,则使用HTTP/2;如果服务器不提供任何信息,则使用HTTP/1.1

我读过一些关于ALPN的文章,这似乎是可能的,但我没有发现任何东西同时支持这些协议。我没能把它们插在一起


我目前正在使用和。

解决方案可以是使用nginx(或apache2)作为反向代理来处理该需求


Nginx可以将jetty服务器(仅使用http/1.1或http/2协议)和带有alpn的服务器http/2(最新版本)代理给客户端。

事实上,从JDK9开始,只有jdk才支持alpn


这不是JAX-RS客户机api所能解决的问题。如果这个问题仍然存在,那么有一种方法可以实现 如您所知,如果使用TLSv1.2(h2),HTTP/2需要ALPN支持

只要在平台上安装了openssl(1.0.2版或更高版本),该软件包对HTTP/2有一定的支持

Netty包将通过调用本机库使用OpenSSL来支持ALPN

我们用JDK8实现了一个客户机,并为服务器只接受http2请求的操作生成了http2请求。我们使用了下面提到的依赖项

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <!--<version>5.0.0.Alpha2</version> -->
        <version>4.1.29.Final</version>
    </dependency>

伊奥·内蒂
讨厌的
4.1.29.最终版本

抽象地说,您的问题是,您需要一个Java servlet,它可以协商和终止单个REST端点,因此避免HTTP/1使用一个接口,HTTP/2使用另一个接口,并避免外部终止,比如通过可以处理多个协议的代理。因此,这是一个集所有功能于一体的servlet

Stuart(&JBoss Peops)已经在Undertow中实现了这一点,至少在2017年,Steve Hu添加了测试用例和PR

您需要在选项映射中传入ENABLE_HTTP2选项。对于 http URI的这意味着客户端将尝试在 第一个请求,https URI的ALPN将用于尝试和协商 HTTP/2。这就是浏览器的行为方式,即使目标 不支持HTTP/2


看起来Simone正在推动变革,以便在Jetty中实现这一点。因此,如果您现在想要这样做,请从Jetty切换到Undertow,或者将问题更改为“在Jetty中支持…”。

Java 11提供的Java HTTP客户端支持HTTP/1.1和HTTP/2(请参阅)

我已经建立了一个连接器使用它。 您可以使用它添加以下依赖项

<dependency>
  <groupId>com.github.nhenneaux.jersey.connector.httpclient</groupId>
  <artifactId>jersey-httpclient-connector</artifactId>
  <version>0.2.2</version>
</dependency>

com.github.nhenneaux.jersey.connector.httpclient


您希望使用Jetty来支持基于ALPN的交通工具的动态选择。这样,您将只编写一个适用于两种协议的Jersey传输。谢谢@我刚刚创建了sbordet,您是否尝试在您的应用程序中使用任何异步调用application@SaurabhJhunjhunwala只需暂时同步,这可能是一个解决方案。但是有几个缺点,即您需要在反向代理中破坏TLS加密,您必须更改服务器,而它可能是外部方,您必须在客户端中选择一个协议,而问题的关键是客户端支持两个协议。可以使用库(Jetty ALPN)来支持它使用JVM的TLS客户端或使用另一个TLS客户端(例如conscrypt)。如果底层传输处理它,则可以通过JAX-RS处理它。目前只有Jetty项目想要实现它。好吧,但要实现JAX-RS,您需要使用现有的http客户端实现,我想Jetty的HttpClient可以为您处理ANPL?我使用JAX-RS的Jersey实现,它使用Underthe hood Java
HttpUrlConnection
HTTP1客户端。还可以配置Jetty HTTP/1.1客户端。我还写了一封信。但是,使用ALPN没有支持HTTP/1.1和HTTP/2的底层传输。实际上,我正在寻找一个能够同时支持这两种功能的客户端,我不认为您的客户端同时支持HTTP/1和HTTP/2?我的客户端同时支持HTTP/1.1和HTTP/2。默认情况下,它使用HTTP/1.1&对于仅接受HTTP/2的特定服务,我们创建HTTP/2请求它可以从ALPN输出协议中动态选择吗?应用程序已经知道仅支持HTTP/2的特定服务,并且如果调用此服务,然后我们构建ssl上下文和HTTP/2所需的请求。好的,我已经完成了这项工作(我有一个单独的HTTP/1和HTTP/2客户端,请参阅问题中的链接)但不是动态的,这实际上是我的问题。这看起来很有希望,但实际上我还没有找到一种方法来集成JAX-RS和一个HTTP客户机,该客户机支持HTTP/1和HTTP/2,具体取决于目标服务器。据我所知,没有一个带有JAX-RS实现的Undertown客户机连接器?Simone的实现与我在Jetty中创建的问题有关。但是,如果有另一个连接器能够连接HTTP/1和HTTP/2,我可以切换;-)Undertow已经集成为Wildfly的servlet,Wildfly有JAX-RS,它实现为RESTEasy b/c。。。这是一个JBoss项目,不是Apache项目,但两者都可以。我也很想在它上面尝试一下你的场景来验证它是否有效,那么你有一个公开的测试用例吗?实际上我不想要Servlet实现,而是HTTP JAX-RS客户端实现,除非我错过了什么,否则它似乎不会被Undertown实现?啊,我误解了。太棒了!非常感谢。问题仍然是为什么这不是泽西的默认值。