This is the second in a series of articles looking at some of the JDK Enhancement Proposals (JEPS) hoping to make their way into Java 9. Last week we looked at JShell. This week, after looking at the good, the bad and the ugly the focus is on HTTP/2 in JEP 110.

This proposal aims to define a new HTTP client API to replace the legacy HttpURLConnection API. The new HTTP client API will implement HTTP/2 and Websocket. They will be in the java.httpclient module, and at the time of writing they are integrated into JDK 9.

HTTP/2

The main difference between HTTP/1.1 and HTTP/2 is how the data is framed and transported between client and server. HTTP/1.1 relies on a request/response cycle: the request is sent to the client, and the server responds. If there is a lot of data, the page can be slow to load. HTTP/2 allows the server to “push” data: it can send back more data than the client requested. This allows it to prioritise and send the data crucial for loading the webpage first, without waiting for the client to make an additional request.

In addition, with HTTP/2 requests and responses can be multiplexed. This means that multiple responses can be grouped, rather than have to wait for the previous packet to send. HTTP/1.1 only really allows one outstanding request per TCP connection.

HTTP/1.1

http1.1 client-server comms

HTTP/2

http/2 client server comms

What’s wrong with HttpURLConnection?

The existing HttpURLConnection API and its implementation are outdated. First, the superclass URLConnection API was designed with multiple protocols in mind, most of which are now defunct.

Second the HttpURLConnection only works in blocking mode – one thread per request/response pair. This increases the latency and loading times of webpages. It also increases the risk of head-of-line blocking: where a line of packets is waiting for the first packet to be sent. As a workaround, it became common (or, essential) to open several connections to the server. However the HTTP/1.1 standard recommends strongly that a single-user client should not maintain any more than 2 connections with any server.

See How HTTP/2 Is Changing Web Performance Best Practices for more information.

What to expect from the HTTP/2 Client

There are existing HTTP client APIs and implementations outside Java 9, e.g. Jetty and the Apache HttpClient. However according to JEP 110, they are heavyweight in terms of packages and classes. The goals of JEP 110 are to create a simple and concise API that caters for 80-90% of use cases. According to the JEP: “This probably means a relatively small API footprint (e.g. one or two classes in java.net) that does not necessarily expose all the capabilities of the protocol”.

The API will support both HTTP/1.1 and HTTP/2. For HTTP/1.1, The client API aims to have performance on a par with the Apache HttpClient library, Netty and Jetty. It aims to have the same or lower memory consumption than the legacy HttpURLConnection and the Apache HttpClient library, Netty and Jetty.

For HTTP/2, it aims to have better scalability and latency than HTTP/1.1, as well as comparable performance to Apache HttpClient, Netty and Jetty, and lower or the same memory consumption.

It will be lightweight and have several new classes. Some examples are

Example request and response

      // GET
      HttpResponse response = HttpRequest
          .create(new URI("http://www.foo.com"))
          .headers("Foo", "foovalue", "Bar", "barvalue")
          .GET()
          .response();

      int statusCode = response.statusCode();
      String responseBody = response.body(asString());

      // POST
      response = HttpRequest
          .create(new URI("http://www.foo.com"))
          .body(fromString("param1=foo,param2=bar"))
          .POST()
          .response();

Example from the Java 9 documentation.

With HTTP/2, the server can return multiple responses (server pushes) to the client request. These are handled using the HttpResponse.MultiProcessor.

The request/response can be synchronous or asynchronous:

  • Synchronous: the response blocks until the entire request has been sent and the response status code and headers have been received.
  • Asynchronous: responseAsync sends the request. The response is returned asynchronously, after an immediate CompletableFuture<HttpResponse>.
  • Multiple asynchronous responses: multiResponseAsync sends the request asynchronously. Multiple responses are expected. However it can also be used for single responses (e.g with HTTP/1.1).

WebSockets

WebSockets are not new to Java, and are part of the Java EE 7 standard. JEP 110 enables you to easily set up the WebSocket handshake.

WebSocket is a computer communications protocol. It allows the transmission of data in two directions at the same time across a single TCP connection. They are not a HTTP connection, but use HTTP to bootstrap a WebSocket connection. They do this using an Upgrade Header, which the client uses to indicate that it wants to upgrade to a different protocol.

websocket

The Java 9 Websocket API is created using a builder. Once opened, it is ready to send and receive messages. Invoke abort to close abruptly, otherwise sendClose.

Text and binary can be sent across the WebSocket, as well as pings. Messages are sent through the sendX methods and received through WebSocket.Listener.onX methods asynchronously.

Further reading

JEP 110: HTTP/2 Client

Simone Bordet’s talk HTTP 2 0 & Java: Current Status at Devoxx BE 2015

Look out for Oracle’s Michael McMahon talk at Devoxx BE 2016 on The New HTTP Client API in JDK 9

Next up: The JVM

Java 9 series: HTTP/2 Client

| Java Language| 3,479 views | 0 Comments
About The Author
- Katharine is a Java developer by trade, turned Community & Content Manager for Voxxed. Helping developers learn and share knowledge. Contact me at kbe@voxxed.com with any news, articles or tutorials.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>