Java9系列第九篇-对HTTP2协议的支持与非阻塞HTTP-API

在HTTP/1.1 发布了16 年之后,IETF在2015年终于通过了HTTP/2 协议。HTTP/2协议旨在降低延迟,满足当今时代对于信息响应时间的要求。在这篇文章中,我会简要的对HTTP/2协议进行介绍,然后我们将重点放在研究Java9中对HTTP/2支持及其HTTP客户端API的变化。
一、HTTP/2简介
- HTTP/2 旨在减轻 HTTP/1.1 维护复杂基础结构所造成的痛苦,性能良好。尽管 HTTP/2 仍然与 HTTP/1.1 向后兼容,但它不再是基于文本的协议。
- HTTP/2 多路复用使单个连接可以处理多个双向流,允许客户端通过单个连接同时下载多个资源。
- HTTP 1.x 协议是基于文本的,因此报文很冗长。有的时候,同一组 HTTP Headers被一遍又一遍地交换。HTTP/2 通过跨请求维护 HTTP Headers,消除重复交换的数据,大大减少了数据交互所需的带宽。
HTTP/2数据推送
您可能认为HTTP/2的服务端数据推送是对 WebSockets 的某种延续或升级,但情况并非如此。虽然 WebSockets 是客户端和服务器之间全双工通信的一种方法,以便服务器在建立 TCP 连接后将数据发送到客户端,但 HTTP/2 提供了一种不同的解决方案。
HTTP/2 推送是主动向客户端发送资源,而无需从客户端的角度发起资源请求。这意味着服务器端根据一个请求可能知道网站进一步需要的其他资源,并且早在客户端再次发起请求它们之前,就可以一并(提前)发送所有资源。
目前支持 HTTP/2 的 Java HTTP 客户端
- Jetty
- Netty
- OkHttp
- Vert.x
- Firefly
但是在这篇文章中,我们不会介绍这些Java 客户端软件,而是介绍Java9提供的HTTP/2支持。
二、Java 9 的 HTTP/2 客户端
首先使用Java 9的语法进行模块的导入 。jdk.incubator.httpclient
module com.springui.echo.client {
requires jdk.incubator.httpclient;
}
Java 9 新的 HTTP Cient API 遵循构建器模式。HttpClient是用来操作HTTP请求的入口点,先构建后使用。
HttpClient client = HttpClient
.newBuilder()
.version(Version.HTTP_2) //支持HTTP2
.build();
在阻塞模式下发送请求
一旦我们有了一个 HttpClient实例,就可以用它来发送HttpRequest,HttpRequest实例也可以使用构造器创建。
HttpResponse<String> response = client.send(
HttpRequest
.newBuilder(TEST_URI) //请求地址
.POST(BodyProcessor.fromString("Hello world")) //POST报文数据
.build(),
BodyHandler.asString() //请求响应数据处理,接收字符串
);
请求发出去之后,线程会一直阻塞直到得到响应数据,这个和JAVA 8及之前的HTTP API是一样的。但是Java 9提供了以异步非阻塞发送处理请求的方法,更适合高并发的HTTP请求与处理。
以非阻塞模式发送请求(Java 9)
在下面的示例中,10 个随机整数以异步方式发送请求。
List<CompletableFuture<String>> responseFutures =
IntStream.of(1,2,3,4,5,6,7,8,9,10) //10个整数形成IntStream,Java 8的语法
.mapToObj(String::valueOf) //10个整数转换成字符串,Java 8的语法
.map(message -> client.sendAsync( //将10个整数字符串作为内容,发送10个异步请求
HttpRequest.newBuilder(TEST_URI)
.POST(HttpRequest.BodyProcessor.fromString(message))
.build(),
HttpResponse.BodyHandler.asString()
).thenApply(HttpResponse::body) //以CompletableFuture<HttpResponse.body()>作为流处理的返回值
)
.collect(Collectors.toList()); //将Stream转成List
上面的例子大量的使用了Java 8的Stream流式处理的API,如果不熟悉的同学,可以翻看我以前写的一些文章。
sendAsync方法的返回值CompletableFuture<HttpResponse<String>>,使用thenApply(HttpResponse::body)作了进一步的处理,最终返回值是CompletableFuture<String>。
CompletableFuture是Java异步编程的知识,将并发的异步处理结果打印出来。
responseFutures.stream().forEach(future -> {
LOGGER.info("Async response: " + 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 Client API与HTTP/2结合最紧密的就是:可以使用HTTP2发送一个请求,得到多个异步数据结果。(某些数据提前推送,当然这需要服务端也支持HTTP/2进行配合)
Map<HttpRequest,CompletableFuture<HttpResponse<String>>> responses =
client.sendAsync( //注意这里只发送一次请求
HttpRequest.newBuilder(TEST_URI)
.POST(HttpRequest.BodyProcessor.fromString(TEST_MESSAGE))
.build(),
HttpResponse.MultiProcessor.asMap( //多个资源的响应结果
request -> Optional.of(HttpResponse.BodyHandler.asString())
)
).join();
responses.forEach((request, responseFuture) -> {
LOGGER.info("Async response: " + responseFuture.getNow(null));
});
从Java 9的角度来看,新的HTTP/2客户端API看起来不错。但笔者觉得目前相关技术的使用还不是很成熟,我觉得大家暂时尝尝鲜就可以。
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学Spring Boot2.0》
- 《Spring Security-JWT-OAuth2一本通》
- 《实战前后端分离RBAC权限管理系统》
- 《实战SpringCloud微服务从青铜到王者》
- 《VUE深入浅出系列》
Java9系列第九篇-对HTTP2协议的支持与非阻塞HTTP-API的更多相关文章
- 老猿学5G扫盲贴:推荐三篇介绍HTTP2协议相关的文章
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 5G中的服务化接口调用都是基于HTTP2协议的,老 ...
- java9系列第二篇-资源自动关闭的语法增强
我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...
- 【Windows编程】系列第九篇:剪贴板使用
上一篇我们学习了常见的通用对话框,本篇来了解剪贴板的使用,它常用于复制粘贴功能. 剪贴板是Windows最早就加入的功能,由于该功能非常实用,我们几乎每天都会使用到.通过剪贴板,我们就可以将数据从一个 ...
- MongoDB基础教程系列--第九篇 MongoDB 分片
1.分片介绍 分片(sharding)是将数据拆分,将其分散存到不同机器上的过程.MongoDB 支持自动分片,可以使数据库架构对应用程序不可见.对于应用程序来说,好像始终在使用一个单机的 Mongo ...
- javascript运动系列第九篇——碰撞运动
× 目录 [1]碰撞检测 [2]无损碰撞 [3]有损碰撞 前面的话 碰撞可以分为碰壁和互碰两种形式,上篇介绍了碰壁运动,本文将从浅入深地介绍碰撞运动的互碰形式 碰撞检测 对于互碰形式的碰撞运动来说,首 ...
- 深入理解ajax系列第九篇——jQuery中的ajax
前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...
- 深入理解ajax系列第九篇
前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...
- K8S系列第九篇(持久化存储,emptyDir、hostPath、PV/PVC)
更多k8s内容,请关注威信公众好:新猿技术生态圈 一.数据持久化 Pod是由容器组成的,而容器宕机或停止之后,数据就随之丢了,那么这也就意味着我们在做Kubernetes集群的时候就不得不考虑存储的问 ...
- netty系列之:netty对SOCKS协议的支持
目录 简介 SocksMessage Socks4Message Socks5Message 总结 简介 SOCKS是一个优秀的网络协议,主要被用来做代理,它的两个主要版本是SOCKS4和SOCKS5 ...
随机推荐
- Java 内存模型(Java Memory Model,JMM)
基本概念 JMM 本身是一种抽象的概念并不是真实存在,它描述的是一组规范,通过这组规范定义了程序的访问方式 JMM 同步规定 线程解锁前,必须把共享变量的值刷新回主内存 线程加锁前,必须读取主内存的最 ...
- Struts2+Spring4.2+Hibernate4.3整合
一.导包 antlr-2.7.7.jarasm-3.3.jarasm-commons-3.3.jarasm-tree-3.3.jarcom.springsource.com.mchange.v2.c3 ...
- C面向对象: 升级版本实现:同步逻辑、少量连续失败则增补、多次连续失败则拉长同步周期
// C语言之 面向对象+虚事务的抽象 /*********** 进阶练习: (对虚的事物的抽象) 完善部门职责 ***********************/ #include <stdio ...
- Arduino 多线程简单代码
转载: 1. https://www.csdn.net/gather_27/MtTaggzsMDExMS1ibG9n.html 2. https://v.youku.com/v_show/id ...
- Java 使用UDP传输一个小文本文件
工具1:Eclipse 工具2:IntelliJ IDEA Java工程的目录结构(基于IntelliJ IDEA) 例1.1:接收方,因为接收到的数据是字节流,为了方便,这里是基于Apache co ...
- JVM 第二篇:垃圾收集器以及算法
本文内容过于硬核,建议有 Java 相关经验人士阅读. 0. 引言 一说到 JVM ,大多数人第一个想到的可能就是 GC ,今天我们就来聊一聊和 GC 关系最大的垃圾收集器以及垃圾收集算法,希望能通过 ...
- 洛谷 P3413 【萌数】
敲完这篇题解,我就,我就,我就,嗯,好,就这样吧... 思路分析: 首先我们要知道一个回文串的性质--假如说一个[l-1,r+1]的串是回文的,那么[l,r]一定也是回文的. 所以我们只要记录前一个数 ...
- centos7 安装k8s kubectl 客户端
1. 配置k8s的kubelet 管理客户端 1 cat <<EOF > /etc/yum.repos.d/kubernetes.repo 2 [kubernetes] 3 name ...
- 第一月多测师讲解_ linux_vim命令_004
一. vi/vim 编辑器共分为三种模式: 命令模式(Command mode),"ESC" 输入模式(Insert mode) 底线命令模式(Last line mode) 命令 ...
- win10的cortana搜索显示空白
解决方法:重置应用 问题原因:待查明 然后,我们往下拉