JDK11的新特性:HTTP API和reactive streams

简介

JDK11的新特性:新的HTTP API中,我们介绍了通过新的HTTP API,我们可以发送同步或者异步的请求,并获得的返回的结果。

今天我们想探讨一下这些同步或者异步请求和响应和reactive streams的关系。

更多内容请访问www.flydean.com

怎么在java中使用reactive streams

reactive streams的介绍大家可以参考reactive stream协议详解,使用reactive streams的目的就是为了解决发送者和消费者之间的通信问题,发送者不会发送超出消费者能力的信息。

我们再回顾一下reactive streams中的几个关键概念:

  • Publisher 负责产生消息或者事件,并提供了一个subscribed接口来和Subscriber进行连接。

  • Subscriber 用来subscribe一个Publisher,并提供了onNext方法来处理新的消息,onError来处理异常,onComplete提供给Publisher调用来结束监听。

  • Subscription 负责连接Publisher和Subscriber,可以用来请求消息或者取消收听。

更进一步,如果我们想要自己实现一个reactive streams,我们需要做这些事情:

  1. 创建Publisher和Subscriber
  • 创建Publisher和Subscriber。
  • 调用Publisher.subscribe(Subscriber)建立Publisher和Subscriber之间的连接。
  • Publisher创建一个Subscription,并调用Subscriber.onSubscription(Subscription)方法。
  • Subscriber将Subscription保存起来,供后面使用。
  1. 发送和接收信息
  • Subscriber调用Subscription.request(n) 方法请求n个消息。
  • Publisher调用Subscriber.onNext(item) 将请求的消息发送给Subscriber。
  • 按照需要重复上诉过程。
  1. 取消或者结束
  • Publisher调用Subscriber.OnError(err) 或者 Subscriber.onComplete()方法。
  • Subscriber调用Subscription.cancel()方法。

POST请求的例子

还记得上篇文章我们讲HTTP API新特性的时候,我们使用的例子吗?

例子中,我们使用了一个HttpRequest.BodyPublisher,用来构建Post请求,而BodyPublisher就是一个Flow.Publisher:

public interface BodyPublisher extends Flow.Publisher<ByteBuffer>

也就是说从BodyPublisher开始,就已经在使用reactive streams了。

为了能够更好的了解reactive streams的工作原理,我们创建几个wrapper类将Publisher,Subscriber,Subscription包装起来,输出相应的日志。

代码有点多我们就不一一列出来了,这里只列一个CustBodyPublisher的具体实现:

public class CustBodyPublisher implements HttpRequest.BodyPublisher {

    private final HttpRequest.BodyPublisher bodyPublisher;

    public CustBodyPublisher(HttpRequest.BodyPublisher bodyPublisher){
this.bodyPublisher=bodyPublisher;
}
@Override
public long contentLength() {
long contentLength=bodyPublisher.contentLength();
log.info("contentLength:{}",contentLength);
return contentLength;
} @Override
public void subscribe(Flow.Subscriber<? super ByteBuffer> subscriber) {
log.info("CustBodyPublisher subscribe {}",subscriber);
bodyPublisher.subscribe(new CustSubscriber(subscriber));
}
}

wrapper类很简单,通过构造函数传入要wrapper的类,然后在相应的方法中调用实际wrapper类的方法。

最后,我们将之前使用的调用HTTP API的例子改造一下:

    public void testCustPost() throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder().build(); HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers
.ofString("{ 我是body }");
CustBodyPublisher custBodyPublisher= new CustBodyPublisher(requestBody);
HttpRequest postRequest = HttpRequest.newBuilder()
.POST(custBodyPublisher)
.uri(URI.create("http://www.flydean.com"))
.build(); HttpResponse<String> response = client
.send(postRequest, HttpResponse.BodyHandlers.ofString()); log.info("response {}",response);
}

注意这里CustBodyPublisher custBodyPublisher= new CustBodyPublisher(requestBody),我们创建了一个新的wrapper类。

运行它,观察输出结果:

[HttpClient-1-Worker-0] INFO com.flydean.CustBodyPublisher - contentLength:14
[HttpClient-1-Worker-0] INFO com.flydean.CustBodyPublisher - CustBodyPublisher subscribe jdk.internal.net.http.Http1Request$FixedContentSubscriber@672776b6
[HttpClient-1-Worker-0] INFO com.flydean.CustSubscriber - CustSubscriber onSubscribe jdk.internal.net.http.PullPublisher$Subscription@580ce038
[HttpClient-1-Worker-0] INFO com.flydean.CustSubscription - CustSubscription request 1
[HttpClient-1-Worker-0] INFO com.flydean.CustSubscriber - CustSubscriber onNext length 14
[HttpClient-1-Worker-0] INFO com.flydean.CustSubscription - CustSubscription request 1
[HttpClient-1-Worker-0] INFO com.flydean.CustSubscriber - CustSubscriber onComplete
[main] INFO com.flydean.ReactiveHttpUsage - response (POST http://www.flydean.com) 200

可以看到reactive stream的具体工作流程。首先创建了CustBodyPublisher,然后调用了subscribe方法。

接着CustSubscriber调用onSubscribe创建了Subscription。

每次CustSubscription的request方法都会导致CustSubscriber的onNext方法被调用。

最后当CustSubscription再次请求无结果的时候,CustSubscriber调用onComplete方法结束整个流程。

注意,上面的例子中,我们wrapper调用的是BodyPublishers.ofString,其实BodyPublishers中内置了多种BodyPublisher的实现。感兴趣的朋友可以自行探索。

总结

本文讲解了新的HTTP API中reactive Streams的使用。

本文的例子https://github.com/ddean2009/

learn-java-base-9-to-20

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jdk11-http-api-reactive-streams/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

JDK11的新特性:HTTP API和reactive streams的更多相关文章

  1. JDK1.8新特性——Stream API

    JDK1.8新特性——Stream API 摘要:本文主要学习了JDK1.8的新特性中有关Stream API的使用. 部分内容来自以下博客: https://blog.csdn.net/icarus ...

  2. Java SE 6 新特性: 编译器 API

    新 API 功能简介 JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中.在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤: ...

  3. h5新特性 File API详解

    之前一直觉得h5的新特性就是一些新标签呢,直到想研究一下图片上传预览的原理,才发现还是有好多新的api的,只是不兼容ie低版本,挺可惜的, File API在表单中文件输入字段基础上,又添加了一些直接 ...

  4. Java8 新特性 Stream() API

    新特性里面为什么要加入流Steam() 集合是Java中使用最多的API,几乎每一个Java程序都会制造和处理集合.集合对于很多程序都是必须的,但是如果一个集合进行,分组,排序,筛选,过滤...这些操 ...

  5. JDK8~JDK11的新特性

    #JDK 1.8 新特性接口中的静态方法 只能由接口自己调用 接口中的默认方法 可以不被覆盖 #JDK 1.9 新特性(可能在JDK8中被忽略了,没来得及加)接口可以定义私有方法,但是只能让自己调用, ...

  6. Java8 新特性 Stream Api 之集合遍历

    前言 随着java版本的不断更新迭代,java开发也可以变得甜甜的,最新版本都到java11了,但是后面版本也是不在提供商用支持,需要收费,但是java8 依然是持续免费更新使用的,后面版本也更新很快 ...

  7. html5的新特性——拖放API

    在HTML5之前只能使用鼠标事件模拟出"拖放"效果:HTML5专门为拖放提供了7个事件句柄.  被拖动的源对象可以触发的事件: (1)ondragstart:源对象开始被拖动 (2 ...

  8. java8新特性——Stream API

    Java8中有两大最为重要得改变,其一时Lambda表达式,另外就是 Stream API了.在前面几篇中简单学习了Lambda表达式得语法,以及函数式接口.本文就来简单学习一下Stream API( ...

  9. Java8新特性 - Stream API

    Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找.过滤和映射数据等操作.使用Stream API对集合进行操作,就类似与使用SQL执行的数据库 ...

  10. Java 8新特性--Stream API

    Java 8 API添加了一个新的抽象称为流Stream,以一种声明的方式处理数据,可以极大提高程序员的生产力,写出高效.干净.简洁的代码.这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可 ...

随机推荐

  1. 正则表达式re模块---day18

    1.匹配单个字符 import re lst = re.findall(正则表达式,要匹配的字符串) 返回的是列表,按照正则表达式匹配到的内容都扔到列表中 # ### 1.预定义字符集 # \d 匹配 ...

  2. 在矩池云使用ChatGLM-6B & ChatGLM2-6B

    ChatGLM-6B 和 ChatGLM2-6B都是基于 General Language Model (GLM) 架构的对话语言模型,是清华大学 KEG 实验室和智谱 AI 公司于 2023 年共同 ...

  3. Finder Error code -36 “访达” 错误代码-36

    导致这个问题的原因是你的iCloud (iCloud和iCloud Drive是不一样的) 快满了. 如果你想解决这个问题,有以下三个方法: 1.多买苹果iCloud.(是的,苹果现在太恶心了.但这是 ...

  4. 【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题

    问题描述 Azure Cache for Redis 服务在传输和存储数据时是如何加密呢? 问题回答 一:关于Azure cache for Redis服务在数据传输过程中是如何加密的? 为了确保在A ...

  5. 【Azure 应用服务】在Azure上部署一套VUE框架的单页面应用,有什么可以参考的文档呢?

    问题描述 在Azure上部署一套VUE框架的单页面应用,有什么可以参考的文档呢? 问题回答 Azure官方上并没有VUE框架的实例代码,但是可以参考Node JS项目,来进行设置. 在 Azure 中 ...

  6. NebulaGraph v3.3.0 发布:支持子图过滤、和大量性能优化

    NebulaGraph 3.3.0 支持了 GET SUBGRAPH 和 GetNeighbors 的点过滤.引入了大量性能优化,同时,开始对无 tag 顶点的支持默认关闭. 优化 优化了 k-hop ...

  7. docker 系列

    docker 系列 目录 docker 系列 一. docker 定义 1 nameSpnce 命名空间 2 cgroup 控制组 3 为什么使用容器 二. docker 安装 三 .docker 初 ...

  8. Android 混淆打包后gson报错Missing type parameter

    原文: Android 混淆打包后gson报错Missing type parameter - Stars-One的杂货小窝 记录一个简单的bug 在代码中使用了gson将json转为list: va ...

  9. [置顶] drools规则引擎因为内存泄露导致的内存溢出

    进入这个问题之前,先了解一下drools: 在很多行业应用中比如银行.保险领域,业务规则往往非常复杂,并且规则处于不断更新变化中,而现有很多系统做法基本上都是将业务规则绑定在程序代码中. 主要存在的问 ...

  10. Android设备上运行live555的推流程序

    在live555使用NDK21编译出arm64-v8a和armeabi-v7a中我们编译出了v8a和v7a的可执行文件 我们可以使用testH264VideoStreamer程序进行推流 我们将tes ...