运维开发网

新的Java9特性支持HTTP2协议

运维开发网 https://www.qedev.com 2022-09-15 17:16 出处:网络
这篇文章主要为大家介绍了Java9新特性对HTTP2协议的支持与非阻塞HTTP?API,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

这篇文章主要为大家介绍了Java9新特性对HTTP2协议的支持与非阻塞HTTP?API,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪


在HTTP/1.1发布16年后,IETF终于在2015年采用了HTTP/2协议。HTTP/2协议旨在降低延迟,满足当今时代对信息响应时间的要求。在本文中,我将简要介绍HTTP/2协议,然后我们将重点研究Java9中对HTTP/2的支持及其HTTP客户端API的变化。

我计划在接下来的时间里写一系列关于java 9的文章。虽然java 9不像java 8或Java 11那样是核心Java版本,但还是有很多特性值得关注。期待大家的关注,我会把java 9写成系列文章,大概十篇左右。本文为第九篇。


一、HTTP/2简介

HTTP/2旨在缓解HTTP/1.1维护复杂基础设施带来的痛苦,性能良好。尽管HTTP/2仍然向后兼容HTTP/1.1,但它不再是基于文本的协议。

HTTP/2多路复用使单个连接能够处理多个双向流,允许客户端通过单个连接同时下载多个资源。

HTTP 1.x协议是基于文本的,所以消息非常长。有时,同一组HTTP头会反复交换。HTTP/2跨请求维护HTTP头,消除了数据的重复交换,大大降低了数据交互所需的带宽。


HTTP/2数据推送

你可能认为HTTP/2的服务器端数据推送是WebSockets的延续或升级,但事实并非如此。虽然WebSockets是客户端和服务器之间全双工通信的一种方法,以便服务器可以在TCP连接建立后向客户端发送数据,但HTTP/2提供了一种不同的解决方案。

HTTP/2 push是主动向客户端发送资源,而不是从客户端的角度发起资源请求。这意味着服务器端可以根据请求知道网站进一步需要的其他资源,并且可以在客户端再次发起请求之前很久就将所有资源一起(提前)发送。


目前支持 HTTP/2 的 Java HTTP 客户端

码头

妮蒂

网络

垂直x

萤火虫

但在本文中,我们不会介绍这些Java客户端软件,而是Java9提供的HTTP/2支持。


二、Java 9 的 HTTP/2 客户端

首先,使用Java 9的语法导入模块。jdk.incubator.httpclient

modulecom.springui.echo.client{requiresjdk.incubator.httpclient;}

9 Java的新HTTP Cient API遵循builder模式。HttpClient是操作HTTP请求的入口点,首先构建,然后使用。

HttpClientclient=HttpClient.newBuilder().version(Version.HTTP_2)//支持HTTP2.build();


在阻塞模式下发送请求

一旦我们有了HttpClient实例,我们就可以用它来发送HTTP请求,也可以用构造函数来创建HttpRequest实例。

HttpResponselt;Stringgt;response=client.send(HttpRequest.newBuilder(TEST_URI)//请求地址.POST(BodyProcessor.fromString(quot;Helloworldquot;))//POST报文数据.build(),BodyHandler.asString()//请求响应数据处理,接收字符串);

请求发出后,线程会一直阻塞,直到获得响应数据,这和JAVA 8及之前版本的HTTP API是一样的。但是Java 9提供了异步非阻塞的方法来发送处理请求,更适合高并发的HTTP请求和处理。


以非阻塞模式发送请求(Java 9)

在下面的示例中,10个随机整数异步发送请求。

Listlt;CompletableFuturelt;Stringgt;gt;responseFutures=IntStream.of(1,2,3,4,5,6,7,8,9,10)//10个整数形成IntStream,Java8的语法.mapToObj(String::valueOf)//10个整数转换成字符串,Java8的语法.map(message-gt;client.sendAsync(//将10个整数字符串作为内容,发送10个异步请求HttpRequest.newBuilder(TEST_URI).POST(HttpRequest.BodyProcessor.fromString(message)).build(),HttpResponse.BodyHandler.asString()).thenApply(HttpResponse::body)//以CompletableFuturelt;HttpResponse.body()gt;作为流处理的返回值).collect(Collectors.toList());//将Stream转成List

上面的例子大量使用了Java 8的Stream Streaming API。如果不熟悉,可以看看我之前的一些文章。

sendAsync方法的返回值是CompletableFutureltHttpResponseltStringgtgt;,thenApply(HttpResponse::body)用于进一步处理,最终返回值为Completable FutureStringgt。

CompletableFuture是Java异步编程的知识,打印出并发异步处理的结果。

responseFutures.stream().forEach(future-gt;{LOGGER.info(quot;Asyncresponse:quot;+future.getNow(null));});

您会注意到,最终的打印日志可能不会按照1、2、3、4、5、6、7、8、9、10的顺序进行处理,因为所有请求都是异步发送的,返回的结果是CompletableFuture用于异步处理的结果。


三、支持HTTP2的Push-Promise Frames

以上例子都可以在HTTP/1.1协议下完成,只是新增了非阻塞异步API,不涉及HTTP/2特性。不用担心,Java 9客户端API和HTTP/2最紧密的联系就是可以用HTTP2发送一个请求,得到多个异步数据结果。(有些数据是提前推送的,当然需要服务器支持HTTP/2)

Maplt;HttpRequest,CompletableFuturelt;HttpResponselt;Stringgt;gt;gt;responses=client.sendAsync(//注意这里只发送一次请求HttpRequest.newBuilder(TEST_URI).POST(HttpRequest.BodyProcessor.fromString(TEST_MESSAGE)).build(),HttpResponse.MultiProcessor.asMap(//多个资源的响应结果request-gt;Optional.of(HttpResponse.BodyHandler.asString()))).join();responses.forEach((request,responseFuture)-gt;{LOGGER.info(quot;Asyncresponse:quot;+responseFuture.getNow(null));});

从Java 9的角度来看,新的HTTP/2客户端API看起来不错。不过我觉得目前相关技术的使用还不是很成熟,我觉得可以尝试一段时间。

以上就是Java9对HTTP2协议和非阻塞HTTP API的新特性支持的细节。关于支持HTTP2协议和非阻塞HTTP API的更多信息

0

精彩评论

暂无评论...
验证码 换一张
取 消