Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Java 11 HTTP Client API to implement HTTP/2 server push

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how to use Java 11 HTTP Client API to achieve HTTP/2 server push. The editor thinks it is very practical, so I share it with you as a reference. I hope you can get something after reading this article.

Do you still remember HttpUrlConnection? JDK 11 redesigned HTTP Client API for HttpUrlConnection. HTTP Client API is easy to use and supports HTTP/2 (default) and HTTP/1.1. For backward compatibility, HTTP Client API is automatically downgraded from HTTP/2 to HTTP1.1 when the server does not support HTTP/2.

In addition, HTTP Client API supports both synchronous and asynchronous programming models and relies on stream to transfer data (reactive stream). It also supports the WebSocket protocol for real-time Web applications and reduces the communication overhead between the client and the server.

In addition to multiplexing (Multiplexing), another powerful feature of HTTP/2 is server push. In the traditional method (HTTP/1.1), the request HTML page is initiated mainly through the browser, parsing the received tags (Markup) and identifying the referenced resources (such as JS, CSS, images, etc.).

In order to obtain resources, the browser continues to send resource requests (one request for each resource). Instead, HTTP/2 sends HTML pages and referenced resources without requiring an active request from the browser. Therefore, after the browser requests the HTML page, it can receive the page and all the other information needed to display it. HTTP Client API supports the HTTP/2 function through the PushPromiseHandler interface.

The interface implementation must be populated as the third parameter of the send () or sendAsync () method. PushPromiseHandler relies on the following three synergies:

Client-initiated send request (initiatingRequest)

Synthetic push request (pushPromiseRequest)

Acceptor function, which must be called successfully to accept push promise (acceptor)

Call a specific acceptor function to accept push promise. The acceptor function must pass in a BodyHandler (not null) to handle the request body of the Promise. The acceptor function returns an instance of CompletableFuture to complete the promise response.

Based on the above information, take a look at the PushPromiseHandler implementation:

Private static final List

AsyncPushRequests = new CopyOnWriteArrayList ()

...

Private static HttpResponse.PushPromiseHandler pushPromiseHandler () {

Return (HttpRequest initiatingRequest

HttpRequest pushPromiseRequest

Function acceptor)-> {

CompletableFuture 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 ()

}

}

Now, trigger a request to pass PushPromiseHandler to 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")

The complete source code can be found on GitHub.

Github.com/PacktPublishing/Java-Coding-Problems/tree/master/Chapter13/P268_ServerPush

If you want to summarize all the push promise and response into the specified map, you can use the PushPromiseHandler.of () method, as follows:

Privatestatic final ConcurrentMap promisesMap

= new ConcurrentHashMap ()

Privatestatic final Function 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 () {/ / Foreign Exchange documentary 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 pushPromiseHandler () {

Return HttpResponse.PushPromiseHandler.of (promiseHandler, promisesMap)

}

The complete source code can be found on GitHub.

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

OfString () of type String is used by BodyHandler in the previous two solutions. If the server also needs to push binary data (such as images), it is not very suitable. Therefore, if you want to deal with binary data, you need to switch to BodyHandler of type byte [] with ofByteArray (). You can also save push resources to disk with ofFile (). The following solution is an improved version of the previous solution:

Private static final ConcurrentMap

PromisesMap = new ConcurrentHashMap ()

Private static final Function 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 pushPromiseHandler () {

Return HttpResponse.PushPromiseHandler.of (promiseHandler, promisesMap)

} this is the end of the article on "how to use Java 11 HTTP Client API to implement HTTP/2 server push". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report