范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Java11新特性效能翻倍的HttpClient

  古老的背景
  从JDK1.1开始,JDK中就有HttpURLConnection来提供了网络连接的能力,但是由于实现的比较古早,其有很多的局限性。比如HttpURLConnection是通过底层提供的socket连接来进行通信,而每一个HttpURLConnection实例只能发送一个请求,之后只能通过close()释放请求的网络资源,或在持久化连接时用disconnect()来关闭关闭底层socket。而其基类URLConnection是为了支持很多协议而设计的,但诸如FTP这种协议已经不咋用了。
  HttpURLConnection并不是不能使用,由于不需要依赖,在一些demo项目的时候也会偶尔拿来用。但HttpURLConnection本身已经太过古早,并且很难说HttpURLConnection能够胜任包含各种鉴权信息、各种COOKIE信息的访问请求。
  针对这种情况网络上各种大神提供了更多高级的封装,比较流行的有Apache的HttpClient、Okhttp Client、Spring Cloud Feign之类的。这些封装提供了更丰富的资源与更便捷的封装,也支持了更高级功能如HTTP/2协议、异步请求等。
  不过到了JDK9的时候,Java提供了一个新的Http请求工具HttpClient,经过了JDK10的再次预览,最终在JAVA11中作为正式功能提供使用,同时也完全替换了仅有阻塞模式的HttpURLConnection。 HttpClient简介
  作为JDK11中正式推出的新Http连接器,支持的功能还是比较新的,主要的特性有: 完整支持HTTP 2.0 或者HTTP 1.1 支持 HTTPS/TLS 有简单的阻塞使用方法 支持异步发送,异步时间通知 支持WebSocket 支持响应式流
  HTTP2.0其他的客户端也能支持,而HttpClient使用CompletableFuture作为异步的返回数据。WebSocket的支持则是HttpClient的优势。响应式流的支持是HttpClient的一大优势。
  而HttpClient中的NIO模型、函数式编程、CompletableFuture异步回调、响应式流让HttpClient拥有极强的并发处理能力,所以其性能极高,而内存占用则更少。
  HttpClient的主要类有: java.net.http.HttpClient java.net.http.HttpRequest java.net.http.HttpResponse java.net.http.WebSocket(本文就不介绍这个了)
  细节会在后文介绍,但是WebSocket用的比较少,本文就略过了。 核心使用
  HttpClient 的核心类主要就是 HttpClient、HttpRequest以及HttpResponse,它们都是位于java.net.http 包下,接下来对他们进行一下介绍。 HttpClient
  HttpClient类是最核心的类,它支持使用建造者模式进行复杂对象的构建,主要的参数有: Http 协议的版本 (HTTP 1.1 或者 HTTP 2.0),默认是 2.0。 是否遵从服务器发出的重定向 连接超时时间 代理 认证 //可以用参数调整 HttpClient client = HttpClient.newBuilder()                          .version(Version.HTTP_1_1)                          .followRedirects(Redirect.NORMAL)                          .connectTimeout(Duration.ofSeconds(20))                          .proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 8080)))                          .authenticator(Authenticator.getDefault())                          .build();                           //也可以直接全部默认的便捷创建 HttpClient clientSimple = HttpClient.newHttpClient();
  当创建了HttpClient实例后,可以通过其发送多条请求,不用重复创建。 HttpRequest
  HttpRequest 是用语描述请求体的类,也支持通过建造者模式构建复杂对象,主要的参数有: 请求地址 请求方法:GET,POST,DELETE 等(默认是GET) 请求体 (按需设置,例如 GET 不用 body,但是 POST 要设置) 请求超时时间(默认) 请求头 //使用参数组合进行对象构建,读取文件作为请求体 HttpRequest request = HttpRequest.newBuilder()                 .uri(URI.create("http://www.baidu.com"))                 .timeout(Duration.ofSeconds(20))                 .header("Content-type","application/json")                 .POST(HttpRequest.BodyPublishers.ofFile(Paths.get("data.json")))                 .build(); //直接GET访问 HttpRequest requestSimple = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();
  HttpRequest 是一个不可变类,可以被多次发送。 HttpResponse
  HttpResponse没有提供外部可以创建的实现类,它是一个接口,从client的返回值中创建获得。接口中的主要方法为: public interface HttpResponse {         public int statusCode();         public HttpRequest request();         public Optional> previousResponse();         public HttpHeaders headers();         public T body();         public URI uri();         public Optional sslSession();         public HttpClient.Version version();     }
  HttpResponse的返回内容与常识一致,这里就不展开介绍了。 信息发送
  HttpClient中可以使用同步发送或者异步发送。
  同步 send()
  同步发送后,请求会一直阻塞到收到response为止。 final HttpResponse send = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()); System.out.println(send.body());
  其中 send的第二个参数是通过HttpResponse.BodyHandlers的静态工厂来返回一个可以将 response 转换为目标类型T的处理器(handler),本例子中的类型是String。HttpResponse.BodyHandlers.ofString()的实现方法为: public static BodyHandler ofString() {             return (responseInfo) -> BodySubscribers.ofString(charsetFrom(responseInfo.headers())); }
  其中,BodySubscribers.ofString() 的方法实现是: public static BodySubscriber ofString(Charset charset) {     Objects.requireNonNull(charset);     return new ResponseSubscribers.ByteArraySubscriber<>(            bytes -> new String(bytes, charset)     ); }
  可以看到最终是返回了一个ResponseSubscribers ,而Subscribers则是我们之前《JDK9响应式编程》中讨论过的订阅者。这个构造方法的入参Function定义了订阅者中的finisher属性,而这个属性将在响应式流完成订阅的时在onComplete()`方法中调用。
  异步 sendAsync()
  异步请求发送之后,会立刻返回 CompletableFuture,然后可以使用CompletableFuture中的方法来设置异步处理器。 client.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString())         .thenApply(HttpResponse::body)         .thenAccept(System.out::println)         .join();
  而就如同JDK中响应式流中发布者的submit()方法与offer()方法一样,HttpClient中的send()方法知识sendAsync方法的特例,在send()方法中是先调用sendAsync()方法,然后直接阻塞等待响应结束再返回,部分核心代码为:     @Override     public  HttpResponse     send(HttpRequest req, BodyHandler responseHandler)         throws IOException, InterruptedException     {         CompletableFuture> cf = null;          // if the thread is already interrupted no need to go further.         // cf.get() would throw anyway.         if (Thread.interrupted()) throw new InterruptedException();         try {             cf = sendAsync(req, responseHandler, null, null);             return cf.get();         } catch (InterruptedException ie) {             if (cf != null )                 cf.cancel(true);             throw ie;         }       ...
  响应式流
  HttpClient 作为 Request 的发布者 (publisher),将 Request 发布到服务器,作为 Response 的订阅者 (subscriber),从服务器接收 Response。而上文中我们在send()的部分发现,调用链的最底端返回的是一个ResponseSubscribers订阅者。
  当然,就如同HttpResponse.BodyHandlers.ofString(),HttpClient默认提供了一系列的默认订阅者,用语处理数据的转换: HttpRequest.BodyPublishers::ofByteArray(byte[]) HttpRequest.BodyPublishers::ofByteArrays(Iterable) HttpRequest.BodyPublishers::ofFile(Path) HttpRequest.BodyPublishers::ofString(String) HttpRequest.BodyPublishers::ofInputStream(Supplier)  HttpResponse.BodyHandlers::ofByteArray() HttpResponse.BodyHandlers::ofString() HttpResponse.BodyHandlers::ofFile(Path) HttpResponse.BodyHandlers::discarding()
  所以在HttpClient的时候我们也可以自己创建一个实现了Flow.Subscriber>接口的订阅者,用于消费数据。响应式流完整的简单的例子如下: public class HttpClientTest {      public static void main(String[] args) throws IOException, InterruptedException {         final HttpClient client = HttpClient.newHttpClient();         final HttpRequest httpRequest = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();          HttpResponse.BodySubscriber subscriber = HttpResponse.BodySubscribers.fromSubscriber(new StringSubscriber(),StringSubscriber::getBody);         client.sendAsync(httpRequest,responseInfo -> subscriber)                 .thenApply(HttpResponse::body)                 .thenAccept(System.out::println)                 .join();     }      static class StringSubscriber implements Flow.Subscriber>{         Flow.Subscription subscription;         List response = new ArrayList<>();         String body;         public String getBody(){             return body;         }          @Override         public void onSubscribe(Flow.Subscription subscription) {             this.subscription = subscription;             subscription.request(1);         }          @Override         public void onNext(List item) {             response.addAll(item);             subscription.request(1);         }          @Override         public void onError(Throwable throwable) {             System.err.println(throwable);         }          @Override         public void onComplete() {             byte[] data = new byte[response.stream().mapToInt(ByteBuffer::remaining).sum()];             int offset = 0;             for(ByteBuffer buffer:response){                 int remain = buffer.remaining();                 buffer.get(data,offset,remain);                 offset += remain;             }             body = new String(data);         }     } }最后
  HttpClient是JDK11正式上线的高性能Http客户端。其底层基于响应式流,通过上层封装还提供了异步信息发送、同步信息发送,以及其他完成的HTTP协议内容。在进行响应式编程的方面,HttpClient也是一个十分优秀的参照目标。

吴玉新副教授毫米级颗粒在湍流场中的传热及着火特性能源人都在看,点击右上角加关注创新点通过四风扇对冲的电热实验装置,构建了各向同性湍流流场,可通过改变风扇转速及热功率调节湍流强度及环境温度。基于该实验装置研究了湍流强度对毫米级颗粒扩张!光联全球骨干网再增39个PoP点在数字化转型不断深化的时代背景下,近日,光联再度完成骨干网体系升级,从原有的全球83个PoP点升级到现有的122个,进一步扩大了网络服务版图,能够实现快速构建覆盖亚太地区北美洲南美下半年要发布的iPhone14与Mate50哪个更值得期待?最近,外媒整理了iPhone14全系列四款机型的详细参数,今年iPhone14系列共有四款机型,iPhone14iPhone14MaxiPhone14Pro和iPhone14Pro2022年5月发布的几款新机,都很不错,你最期待哪一款?哈喽大家好,我是你们的老朋友小馨,每天都会给大家更新我的原创内容。2022年5月份即将发布的几款新机都有哪些呢?接下来小馨就给大家来梳理一下吧。首先,第一款就是昨天刚刚发布的viv俄遭网络攻击成倍上升,黑客索要金额最高达2。5亿卢布新京报讯(记者陈奕凯实习生朱铭佳)据俄罗斯独立报5月22日报道,自俄罗斯对乌克兰发起特别军事行动以来,俄罗斯国内企业和基础设施遭受的网络攻击成倍上升。黑客索要的敲诈金额最高达2。5奥迪小满广告被指抄袭律师侵犯了信息网络传播权央广网北京5月22日消息(记者黄玉玲)5月21日是农历小满节气,有一条短视频在各大平台频繁刷屏,阅读量轻松达到10万,这条视频的发布者为奥迪。但是,这条视频推出不久,就被北大满哥早关于SRE方法论的一些笔记写在前面阿里系列有一本云原生操作系统Kubernetes中作者在前言里讲到Google开源的Kubernetes和SREGoogle运维解密这本书是剑法和气功的关系换句话讲Kube碳圈如何割年轻人韭菜号称月收入过5万,或超百万人才缺口作者雪小顽林修卫诗婕编辑卫诗婕林修在中国,少有其他行业像过去20年的碳交易领域,历经起落落起的多次沉浮。最早入场的冒险家给这个行业留下了丰富的传说。这门生意也和煤炭这一传统行业一样港股午评恒生科技指数涨4。64重回4000点上方,快手美团涨超8金融界5月11日消息今日早盘港股低开后走高,截至午盘,恒指收涨1。72,报19971。18点恒生科技指数收涨4。64,报4087。5点,重回4000点上方国企指数涨2。41,报68快手服务商入驻门槛要求据了解,在商业化进程提速后,快手迅速成长为中国重要的数字营销平台,取得这一地位源于平台本身庞大的用户基数与越发多元化的用户结构。数据显示,目前快手的日活跃用户数已经突破3亿,快手电疑似小米12Ultra工程机曝光骁龙8Plus徕卡四摄据此前消息,小米12系列的超大杯机型小米12Ultra可能会在6月份发布,在性能和影像等方面会进一步增强,达到安卓顶级水准。今晚,有微博数码博主牛丸科技发文称,在二手市场上出现了疑
王家钧给电动汽车锂电池做脑CT近年来,随着电动汽车兴起,电池起火等安全问题备受关注。从2017年回国至今,哈尔滨工业大学教授青年科学家工作室负责人王家钧始终在寻找这一难题的破解之路。我目前的工作是给电池的健康状小箱子大梦想内藏WAVES音频插件的PSBAlphaAM3桌面式蓝牙音箱音箱和耳机虽都属于音频产品,但在选购上无疑是更具难度的。总是听到各种的抱怨,耳机的问题居多,主要的问题还是戴久了各种不舒服。很多小伙伴其实只是想挑选一款生活中全面性的日用音箱,希望内蒙古一季度电信业务收入增速高于全国平均水平3。43个百分点5月7日,记者从内蒙古自治区政府新闻办召开的新闻发布会获悉,今年一季度,全区电信业务收入累计完成59。25亿元,同比增长11。73,增速高于全国平均水平3。43个百分点。全区工业互联联周边游智能服务平台助力实体商家转型升级随着5G时代和移动互联网的普及,有些线下的实体商家受到了毁灭性的打击,随之兴起的是各大APP和依托社交平台而兴起的社交平台,对于中小商家而言,昂贵的传统电商不是它们所能承受的,想要国家为什么要求企业网络实施网络安全防护措施企业是一个国家创造财富的加工厂。通过企业,可以将物力人力财力融合在一起创造出更多财富,带动社会经济发展。这些企业住在一个大院里,这个大院的名字叫国家。国家为了企业大环境的安全,会搭36氪首发推出RASP应用程序自我防护体系,边界无限完成超千万元级别天使轮融资36氪获悉,北京边界无限科技有限公司(BoundaryX,以下简称边界无限)于今日正式宣布完成天使轮融资。本轮融资投资方为初心资本,金额在超千万元级别。原力资本担任本轮融资独家财务绿盟科技2022合作伙伴大会新产品发布,让企业安全防护如虎添翼云化时代下,企业用户对安全的需求日趋变化,为了更好地满足客户需求,赋能合作伙伴让网络安全更具保障,在2022年合作伙伴大会上,践行云化战略,绿盟科技安全新产品正式发布。绿盟科技集团售价10万的妻子机器人,除了生孩子什么都能做?别被骗了人类对机器人的研发,从最早期的工业机器人,经过不断迭代,衍生出各种形态运用于各领域的机器人。近几年,有消息称日本有一个科研团队研发出了一款妻子机器人,功能非常强大,售价仅卖10万一企业从0开始搭建商业智能(BI)系统,规划准备工作如何落地?随着新一代信息化数字化技术的应用,引发了新一轮的科技革命,现代化社会和数字化的联系越来越紧密,数据也变成继土地劳动力资本技术之后的第五大生产要素,这一切都表明世界已经找准未来方向,美国突发惨案!15人遇害,拜登下令降半旗!科技股暴跌,巨头一夜狂泻43!达里奥现金是垃圾,但股市更垃圾!上海北京最新通报中国基金报记者金宥智刚刚过去的一夜,科技巨头们又遭遇血洗,纳指也大跌,而道指却实现逆转,盘中拉升650点翻红。桥水创始人达里奥周二也突然发声,唱空股市!还有一则新闻令人痛心,周二,奥密克戎毒性有所降低?美国一项研究有了新发现,或与你想的不同众所周知,自从新冠病毒在全球大范围流行后,科学家们从来没有停止过研究的步伐,而且病毒还在不断变异,想要了解它对付它,就不能停下脚步。好在现在虽然还有不少人被感染,但大部分是无症状患