iis服务器助手广告广告
返回顶部
首页 > 资讯 > 服务器 >如何使用Java 11 HTTP Client API实现HTTP/2服务器推送
  • 722
分享到

如何使用Java 11 HTTP Client API实现HTTP/2服务器推送

2023-06-02 14:06:37 722人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关如何使用Java 11 Http Client api实现HTTP/2服务器推送,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。对 HttpUrlConnection 你还有印象

这篇文章将为大家详细讲解有关如何使用Java 11 Http Client api实现HTTP/2服务器推送,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

对 HttpUrlConnection 你还有印象吗?jdk 11为 HttpUrlConnection 重新设计了 HTTP Client API。HTTP Client API 使用简单,支持 HTTP/2(默认)和 HTTP/1.1。为了向后兼容,当服务器不支持 HTTP/2时,HTTP Client API 会自动从 HTTP/2 降到 HTTP1.1。 

此外,HTTP Client API 支持同步和异步编程模型,并依靠 stream 传输数据(Reactive stream)。它还支持 websocket 协议,用于实时 WEB 应用程序,降低客户端与服务器间通信开销。

除了多路复用(Multiplexing),HTTP/2 另一个强大的功能是服务器推送。传统方法(HTTP/1.1)中,主要通过浏览器发起请求 html 页面,解析接收的标记(Markup)并标识引用的资源(例如jsCSS、图像等)。 

为了获取资源,浏览器会继续发送资源请求(每个资源一个请求)。相反,HTTP/2 会发送 HTML 页面和引用的资源,不需要浏览器主动请求。因此,浏览器请求 HTML 页面后,就能收到页面以及显示所需的所有其他信息。HTTP Client API 通过 PushPromiseHandler 接口支持 HTTP/2 功能。 

接口实现必须作为 send() 或 sendAsync() 方法的第三个参数填入。PushPromiseHandler 依赖下面三项协同:

  • 客户端发起的 send request(initiatingRequest)

  • 合成 push request(pushPromiseRequest)

  • acceptor 函数,必须成功调用该函数才能接受 push promise(acceptor)

调用特定 acceptor 函数接受 push promise。acceptor 函数必须传入一个 BodyHandler(不能为 null)用来处理 Promise 的 request body。acceptor 函数会返回一个 CompletableFuture 实例,完成 promise response。

基于以上信息,看一下 PushPromiseHandler 实现:

private static final List<CompletableFuture<Void>>
  asyncPushRequests = new CopyOnWriteArrayList<>();
...
private static HttpResponse.PushPromiseHandler<String> pushPromiseHandler() {
  return (HttpRequest initiatingRequest,
     HttpRequest pushPromiseRequest,
     Function<HttpResponse.BodyHandler<String> ,
     CompletableFuture<HttpResponse<String>>> acceptor) -> {
     CompletableFuture<Void> pushcf =
        acceptor.apply(HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept((b) -> System.out.println(
           "\nPushed resource body:\n " + b));
        asyncPushRequests.add(pushcf);
        System.out.println("\nJust Got promise push number: " +
           asyncPushRequests.size());
        System.out.println("\nInitial push request: " +
           initiatingRequest.uri());
        System.out.println("Initial push headers: " +
           initiatingRequest.headers());
        System.out.println("Promise push request: " +
           pushPromiseRequest.uri());
        System.out.println("Promise push headers: " +
           pushPromiseRequest.headers());
  };
}

现在,触发一个 request 把 PushPromiseHandler 传给 sendAsync():

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
  .uri(URI.create("https://http2.golang.org/serverpush"))
  .build();
client.sendAsync(request,
  HttpResponse.BodyHandlers.ofString(), pushPromiseHandler())
     .thenApply(HttpResponse::body)
     .thenAccept((b) -> System.out.println("\nMain resource:\n" + b))
     .join();
asyncPushRequests.forEach(CompletableFuture::join);
System.out.println("\nFetched a total of " +
  asyncPushRequests.size() + " push requests");

完整源代码可在 GitHub 上找到。

github.com/PacktPublishing/Java-coding-Problems/tree/master/Chapter13/P268_ServerPush

如果要把所有 push promise 及 response 汇总到指定的 map 中,可以使用 PushPromiseHandler.of() 方法,如下所示:

privatestatic final ConcurrentMap<HttpRequest,
  CompletableFuture<HttpResponse<String>>> promisesMap
     = new ConcurrentHashMap<>();
privatestatic final Function<HttpRequest,
  HttpResponse.BodyHandler<String>> promiseHandler
     = (HttpRequest req) -> HttpResponse.BodyHandlers.ofString();
public static void main(String[] args)
        throws IOException, InterruptedException {
  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
     .uri(URI.create("https://http2.golang.org/serverpush"))
     .build();
  client.sendAsync(request,
     HttpResponse.BodyHandlers.ofString(), pushPromiseHandler())
        .thenApply(HttpResponse::body)
        .thenAccept((b) -> System.out.println("\nMain resource:\n" + b))
        .join();function(){   //外汇跟单www.gendan5.com   System.out.println("\nPush promises map size: " +
     promisesMap.size() + "\n");
  promisesMap.entrySet().forEach((entry) -> {
     System.out.println("Request = " + entry.geTKEy() +
         ", \nResponse = " + entry.getValue().join().body());
  });
}
privatestatic HttpResponse.PushPromiseHandler<String> pushPromiseHandler() {
  return HttpResponse.PushPromiseHandler.of(promiseHandler, promisesMap);
}

完整源代码可在 GitHub 上找到。

github.com/PacktPublishing/Java-Coding-Problems/tree/master/Chapter13/P268_ServerPushToMap

前面两个解决方案中 BodyHandler 都用到了 String 类型的 ofString()。如果服务器还需要推送二进制数据(比如图像),就不是很适用。因此,如果要处理二进制数据,则需要用 ofByteArray() 切换到byte[] 类型的 BodyHandler。也可以用 ofFile() 把 push 资源保存到磁盘,下面的解决方案是之前方案的改进版:

private static final ConcurrentMap<HttpRequest,
  CompletableFuture<HttpResponse<Path>>>
     promisesMap = new ConcurrentHashMap<>();
private static final Function<HttpRequest,
  HttpResponse.BodyHandler<Path>> promiseHandler
     = (HttpRequest req) -> HttpResponse.BodyHandlers.ofFile(
       Paths.get(req.uri().getPath()).getFileName());
public static void main(String[] args)
                 throws IOException, InterruptedException {
  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
     .uri(URI.create("https://http2.golang.org/serverpush"))
     .build();
  client.sendAsync(request, HttpResponse.BodyHandlers.ofFile(
     Path.of("index.html")), pushPromiseHandler())
        .thenApply(HttpResponse::body)
        .thenAccept((b) -> System.out.println("\nMain resource:\n" + b))
        .join();
  System.out.println("\nPush promises map size: " +
     promisesMap.size() + "\n");
  promisesMap.entrySet().forEach((entry) -> {
     System.out.println("Request = " + entry.getKey() +
        ", \nResponse = " + entry.getValue().join().body());
  });
}
private static HttpResponse.PushPromiseHandler<Path> pushPromiseHandler() {
  return HttpResponse.PushPromiseHandler.of(promiseHandler, promisesMap);
}

关于“如何使用Java 11 HTTP Client API实现HTTP/2服务器推送”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: 如何使用Java 11 HTTP Client API实现HTTP/2服务器推送

本文链接: https://www.lsjlt.com/news/230391.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用Java 11 HTTP Client API实现HTTP/2服务器推送
    这篇文章将为大家详细讲解有关如何使用Java 11 HTTP Client API实现HTTP/2服务器推送,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。对 HttpUrlConnection 你还有印象...
    99+
    2023-06-02
  • 怎样实现Node.js中的HTTP/2服务器推送
    今天就跟大家聊聊有关怎样实现Node.js中的HTTP/2服务器推送,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。最近Node.js v8.4+版本...
    99+
    2024-04-02
  • 如何使用HTTP/2服务端推送技术加速Node.js应用
    本篇内容介绍了“如何使用HTTP/2服务端推送技术加速Node.js应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能...
    99+
    2024-04-02
  • 如何在Java中使用HTTP实现二维码API?
    在当今数字时代,二维码已经成为了一种非常流行的信息传递方式。许多企业和个人都使用二维码来传递信息和链接。在Java编程中,实现二维码API是一个常见的需求。本文将介绍如何使用Java中的HTTP实现二维码API,并提供一些演示代码。 HTT...
    99+
    2023-08-23
    http 二维码 api
  • Java使用NioSocket手动实现HTTP服务器
    NioSocket简单复习重要概念NioSocket里面的三个重要概念:Buffer、Channel、Selector Buffer为要传输的数据 Channel为传输数据的通道 Selector为通道的分配调度者使用步骤使用NioS...
    99+
    2023-05-31
    java nio socket
  • PHP如何实现HTTP服务器
    这篇文章主要介绍“PHP如何实现HTTP服务器”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP如何实现HTTP服务器”文章能帮助大家解决问题。PHP并非不能实现HTTP服务,一般来讲,这叫网络编...
    99+
    2023-07-05
  • 如何使用 Python 框架的 HTTP API 实现数据交换?
    当今互联网时代,数据交换是各种应用程序之间必不可少的一部分。Python框架的HTTP API是一种常用的数据交换方式,本文将介绍如何使用Python框架的HTTP API实现数据交换。 一、什么是HTTP API? HTTP API是一种...
    99+
    2023-10-06
    框架 api http
  • 如何通过Java代码实现Jetty的Http服务器
    这篇文章主要讲解了“如何通过Java代码实现Jetty的Http服务器”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何通过Java代码实现Jetty的Http服务器”吧!Jetty是一个轻...
    99+
    2023-07-02
  • 使用Go编写API和HTTP:如何实现高效算法?
    在现代软件开发中,API和HTTP已经成为了必不可少的组成部分。而在编写这些服务时,实现高效算法是一个非常重要的问题。本文将介绍如何使用Go编写API和HTTP,并实现高效算法。 一、使用Go编写API Go是一门快速、简单且安全的编程语...
    99+
    2023-07-23
    编程算法 api http
  • Golang如何实现简单http服务器
    这篇文章主要介绍“Golang如何实现简单http服务器”,在日常操作中,相信很多人在Golang如何实现简单http服务器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang如何实现简单http服务器...
    99+
    2023-07-05
  • Django REST框架:如何使用HTTP API构建Web服务?
    Django REST框架是一个基于Django的强大的Web API框架,它使得构建Web服务变得更加容易和快速。本文将介绍如何使用Django REST框架来构建HTTP API服务。 安装Django REST框架 首先,需要安...
    99+
    2023-11-12
    django http git
  • 如何用Netty实现高效的HTTP服务器
    1 概述 HTTP 是基于请求/响应模式的:客户端向服务器发送一个 HTTP 请求,然后服务器将会返回一个 HTTP 响应。Netty 提供了多种编码器和解码器以简化对这个协议的使用...
    99+
    2024-04-02
  • 在java项目中使用 Socket如何实现模拟一个HTTP服务器
    这篇文章给大家介绍在java项目中使用 Socket如何实现模拟一个HTTP服务器,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。HTTP基于TCP协议,协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请...
    99+
    2023-05-31
    java socket http
  • Java容器中如何使用Django框架实现HTTP协议?
    Django是一个基于Python语言的Web框架,它可以帮助开发者快速构建出具有良好可维护性的Web应用程序。而Java容器是指能够运行Java应用程序的环境,如Tomcat、Jetty等。在本文中,我们将探讨如何在Java容器中使用D...
    99+
    2023-06-15
    http django 容器
  • 深入了解HTTP重定向:如何在Linux服务器上使用Java实现
    HTTP重定向是一种非常常见的网络技术,它允许服务器将客户端的请求重定向到其他的URL上。在本文中,我们将深入了解HTTP重定向的原理和如何在Linux服务器上使用Java实现HTTP重定向。 HTTP重定向的原理 HTTP重定向是通过服务...
    99+
    2023-10-24
    linux http 重定向
  • 如何使用Node.js搭建HTTP服务器
    这篇文章将为大家详细讲解有关如何使用Node.js搭建HTTP服务器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是 HTTP 服务?HTTP 协议是什么?超文本传输协议,一个应用层协议,一个在计算机...
    99+
    2023-06-15
  • 如何使用 Java 对象实现高效的 HTTP 加载?
    HTTP(Hypertext Transfer Protocol)是一种用于传输数据的协议,是现代网络应用的基础。在 Java 中,我们可以使用 HttpURLConnection 类来进行 HTTP 请求。然而,使用 HttpURLCo...
    99+
    2023-07-27
    对象 http load
  • Java中如何使用HTTP协议实现二维码生成?
    二维码是一种方便快捷的信息传输方式,越来越受到人们的欢迎。在Java中,我们可以使用HTTP协议来实现二维码的生成。本文将详细介绍如何使用HTTP协议实现二维码生成。 一、HTTP协议简介 HTTP协议是Hyper Text Transf...
    99+
    2023-06-03
    http 二维码 laravel
  • Intellij IDEA 的maven项目通过Java代码实现Jetty的Http服务器(推荐)
    目录一、添加 pom.xml二、在maven 加载 jetty三、新建AttendentConsoleHttpServlet.java四、在App.java 中 加入五、运行 jav...
    99+
    2024-04-02
  • 如何使用golang中的net/http/httptest.NewServer函数启动临时的HTTP服务器
    如何使用golang中的net/http/httptest.NewServer函数启动临时的HTTP服务器在开发Golang的Web应用程序时,有时我们需要启动一个临时的HTTP服务器来进行测试或者模拟某些服务。Golang标准库中的net...
    99+
    2023-11-18
    Golang net/http httptestNewServer
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作