溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java9對HTTP2協(xié)議支持與非阻塞HTTP?API實例分析

發(fā)布時間:2022-03-16 09:08:38 來源:億速云 閱讀:178 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹了Java9對HTTP2協(xié)議支持與非阻塞HTTP API實例分析的相關知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java9對HTTP2協(xié)議支持與非阻塞HTTP API實例分析文章都會有所收獲,下面我們一起來看看吧。

一、HTTP/2簡介

HTTP/2 旨在減輕 HTTP/1.1 維護復雜基礎結構所造成的痛苦,性能良好。盡管 HTTP/2 仍然與 HTTP/1.1 向后兼容,但它不再是基于文本的協(xié)議。

HTTP/2 多路復用使單個連接可以處理多個雙向流,允許客戶端通過單個連接同時下載多個資源。

HTTP 1.x 協(xié)議是基于文本的,因此報文很冗長。有的時候,同一組 HTTP Headers被一遍又一遍地交換。HTTP/2 通過跨請求維護 HTTP Headers,消除重復交換的數(shù)據(jù),大大減少了數(shù)據(jù)交互所需的帶寬。

HTTP/2數(shù)據(jù)推送

您可能認為HTTP/2的服務端數(shù)據(jù)推送是對 WebSockets 的某種延續(xù)或升級,但情況并非如此。雖然 WebSockets 是客戶端和服務器之間全雙工通信的一種方法,以便服務器在建立 TCP 連接后將數(shù)據(jù)發(fā)送到客戶端,但 HTTP/2 提供了一種不同的解決方案。

HTTP/2 推送是主動向客戶端發(fā)送資源,而無需從客戶端的角度發(fā)起資源請求。這意味著服務器端根據(jù)一個請求可能知道網(wǎng)站進一步需要的其他資源,并且早在客戶端再次發(fā)起請求它們之前,就可以一并(提前)發(fā)送所有資源。

目前支持 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();

在阻塞模式下發(fā)送請求

一旦我們有了一個 HttpClient實例,就可以用它來發(fā)送HttpRequest,HttpRequest實例也可以使用構造器創(chuàng)建。

HttpResponse<String> response = client.send(
    HttpRequest
        .newBuilder(TEST_URI)  //請求地址
        .POST(BodyProcessor.fromString("Hello world")) //POST報文數(shù)據(jù)
        .build(),
    BodyHandler.asString()  //請求響應數(shù)據(jù)處理,接收字符串
);

請求發(fā)出去之后,線程會一直阻塞直到得到響應數(shù)據(jù),這個和JAVA 8及之前的HTTP API是一樣的。但是Java 9提供了以異步非阻塞發(fā)送處理請求的方法,更適合高并發(fā)的HTTP請求與處理。

以非阻塞模式發(fā)送請求(Java 9)

在下面的示例中,10 個隨機整數(shù)以異步方式發(fā)送請求。

List<CompletableFuture<String>> responseFutures = 
        IntStream.of(1,2,3,4,5,6,7,8,9,10)  //10個整數(shù)形成IntStream,Java 8的語法
        .mapToObj(String::valueOf) //10個整數(shù)轉(zhuǎn)換成字符串,Java 8的語法
        .map(message -> client.sendAsync( //將10個整數(shù)字符串作為內(nèi)容,發(fā)送10個異步請求
                HttpRequest.newBuilder(TEST_URI)
                        .POST(HttpRequest.BodyProcessor.fromString(message))
                        .build(),
                HttpResponse.BodyHandler.asString()
             ).thenApply(HttpResponse::body)  //以CompletableFuture<HttpResponse.body()>作為流處理的返回值
        )
        .collect(Collectors.toList());  //將Stream轉(zhuǎn)成List

上面的例子大量的使用了Java 8的Stream流式處理的API,如果不熟悉的同學,可以翻看我以前寫的一些文章。

sendAsync方法的返回值CompletableFuture<HttpResponse<String>>,使用thenApply(HttpResponse::body) 作了進一步的處理,最終返回值是CompletableFuture<String>。

CompletableFuture是Java異步編程的知識,將并發(fā)的異步處理結果打印出來。

responseFutures.stream().forEach(future -> {
    LOGGER.info("Async response: " + future.getNow(null));
});

你會注意到,最終的打印日志可能不是按照順序1、2、3、4、5、6、7、8、9、10進行處理的,因為所有的請求都是異步發(fā)送出去的,返回的結果是CompletableFuture用于異步處理的結果。

三、支持HTTP2的Push-Promise Frames

以上所有示例在 HTTP/1.1協(xié)議下都可以完成,只是新加了非阻塞的異步API,也沒涉及到 HTTP/2 特性啊。別急,Java 9 Client API與HTTP/2結合最緊密的就是:可以使用HTTP2發(fā)送一個請求,得到多個異步數(shù)據(jù)結果。(某些數(shù)據(jù)提前推送,當然這需要服務端也支持HTTP/2進行配合)

Map<HttpRequest,CompletableFuture<HttpResponse<String>>> responses =
        client.sendAsync(    //注意這里只發(fā)送一次請求
          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看起來不錯。但筆者覺得目前相關技術的使用還不是很成熟,我覺得大家暫時嘗嘗鮮就可以。

關于“Java9對HTTP2協(xié)議支持與非阻塞HTTP API實例分析”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“Java9對HTTP2協(xié)議支持與非阻塞HTTP API實例分析”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI