JavaData & JavaExploring the Servlet 4.0 APIs of Java EE 8

Exploring the Servlet 4.0 APIs of Java EE 8

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Servlet 4.0 is a major update brought forth with the long-awaited release of Java EE 8. The key aspect of this update is the recent worldwide rollout of the HTTP/2 protocol. Unlike its predecessor, HTTP2 is designed to leverage the power of TCP with the primary target to improve overall performance of information throughput over the HTTP network. The new Servlet 4.0 API accommodates the features which will play an important role in the development arena of JSP, JSF, JAX-RS, and MVC (JSR 371). This article delves into the overall concept behind the changes and the new APIs, with a glimpse at the HTTP changes.

Overview

Servlet 4.0 is designed to leverage the HTTP/2 protocol. Prior to this, the improvements—such as non-blocking asynchronous IO or security improvements, and so forth (Servlet 3.1 – JSR 340)—were mainly targeted towards HTTP/1.1. Servlet 4.0 is a major change with respect to its support of the HTTP/2 standard. Therefore, with HTTP/2 as the key theme, Servlet 4.0 brings a lot of improvements and is decisive of the way servlet programming will be done from now onwards. In real a scenario, the changes from HTTP/1.x to HTTP/2 is, however, going to be a gradual one because a lot is at stake with HTTP/1.x. There are applications in the production, browsers, and so forth that simply cannot be updated overnight. But, in view of the advantages it has over HTTP/1.x, the rollout is certain within a few years.

HTTP/1.x

Although HTTP/1.x has served the Web well over couple of decades, one of the major problems with HTTP/1.x is that it is inadequate to use the full power of TCP communication. This is means that TCP may be revamped or replaced in future (who knows, there are already many alternatives); still, it has been inadequately used by HTTP/1.x. And, the Web, by the way, has gone through tremendous changes. Web pages became heavier with resource-intensive contents; at the same time, the demand for responsiveness is a must. The page loading norms with HTTP remained almost the same because HTTP practically uses one outstanding request per TCP connection. Later, this has been modified to use multiple TCP connections to issue parallel requests, yet there were limits to it. So, in a way, even if you have a huge bandwidth, Web performance still may suffer because of HTTP. Developers succumbed to the problem to an extent by innovatively creating the Web pages with hacks and tricks. For example, loading many small pictures requires issuing multiple requests. HTTP/1.1 is bad at dealing with multiple requests. So, what developers did is innovatively applied a workaround technique called image spriting. Because loading a single big image is faster than loading many small images, a large image is used and then JavaScript or CSS is used to cut out smaller pieces as an individual image to use in the Web page. Another common hack used is called sharding. With this technique, two or more host names were used to get more than one connection, which consequently decreased page load time. Initially, with HTTP1.1, the connection limit was two. Later, it is increased to eight per host name. Clever developers tricked this limit to use more than 100 or more connections; that made HTTP perform well. Note that these are all workaround techniques that normally should have been avoided but developers had no other choice, given the limitation of HTTP/1.x and the demand for responsive, resource-intensive Web content.

HTTP/2

In a way, HTTP/2 therefore emerged from the piled-up discontent, but it too is long overdue for an update to fit according to changing time. Google has been already working on a project, called SPDY, as an alternative to HTTP/1.x. The shift from HTTP/1.x to HTTP/2 has a lot of corporate stakes that required an approval of a tested workable solution with a tinge of diplomacy to gather a general consensus among stakeholders. There cannot be a win-win situation to begin with, but it would definitely benefit everyone in the future. Therefore, after the call for proposals and the selection process, SPDY/2 was chosen as the basis of HTTP/2. The draft was finalised under the aegis of HTTP Working Group of IETF. The distinctive aspects of HTTP/2, unlike its predecessors, are as follows:

  • HTTP/2 is a binary protocol whereas HTTP/1.x was text based. Binary protocols can be more efficiently parsed and are less prone to error.
  • The biggest problem of HTTP/1.1 is the issue of pipelining. This means that there can be only one request outstanding per connection at an instance of time. Although later versions tried to fix it, it failed to eradicate the problem. As a result, a large request or a slow response almost always blocked the content behind it from loading. Clients applied different tricks to overcome them, but they are mainly heuristic techniques and do not address the problem. HTTP/2, therefore, takes this problem head on and is designed to be fully multiplexed.
  • In HTTP/1, browsers often unfairly monopolized network resources by opening more than one connection simultaneously. HTTP/2 solved this problem by enabling a single connection to open multiple concurrent streams on both endpoints that interleave frames from multiple streams.
  • HTTP is a stateless protocol; therefore, the request-response round-trip causes considerable delay even for low resource-intensive Web pages. It is observed that even a little compression of headers can have considerable impact on the request-response round-trip. HTTP/2, therefore, uses header compression to reduce this overhead.
  • The HTTP/2 protocol uses a proactive technique called “Server Push” which also may be called “cache push” that, in short, supplies the resource before the client asks for it. This idea forces the browser to be more responsive and quick.

Servlet 4.0

Perhaps the most distinctive feature of Servlet 4.0 due to HTTP/2 is the implementation of the server push capability. The central idea of this technique is that if the client requests a certain resource, the server proactively assumes that some other related resources also may be asked for soon. As a result, it supplies them into cache before they are actually needed. This availability of resources makes the browser more responsive. For example, it is highly likely that when a Web page is loaded, it may soon request a style sheet CSS document or a header image. The server proactively starts pushing the bytes of these assets simultaneously without the need for the client to make an explicit request. It automatically receives the assets or the server pushes them when the page begins to load.

Servlet 4.0 API supplies a PushBuilder interface in the javax.servlet.http package. A reference of this interface is obtained from the HttpServletRequest, then it populates the builder instance with assets and finally invokes the push() method. According to the API Documentation, the push request will be constructed on the following basis:

  • The request method is set to GET.
  • The path will not be set. This must be set explicitly via a call to path(String).
  • Conditional, range, expectation, authorization, and referrer headers will be removed.
  • Cookies added to the associated response will be added to the push request unless maxAge <= 0, in which case any request cookie with the same name will be removed.
  • The referer header will be set to HttpServletRequest.getRequestURL() plus, if present, the query string from HttpServletRequest.getQueryString().

Here is a code snippet to illustrate how it is written in a servlet class which, for example, pushes resources such as an image, a style sheet, and JavaScript content to the JSP file called index.jsp.

package org.mano.servletpush.examples;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/pushservlet")
public class ServerPushServlet extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest request,
      HttpServletResponse response)
   throws ServletException, IOException {
      request.newPushBuilder().path("css/style1.css").push();
      request.newPushBuilder().path("images/banner.jpg").push();
      request.newPushBuilder().path("js/app.js").push();
      request.getRequestDispatcher("jsp/index.jsp")
         .forward(request, response);
   }
}

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
   <head>
      <title>index</title>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,
         initial-scale=1.0">
      <link href="style1.css" rel="stylesheet"
         type="text/css"/>
   </head>
   <body>
      <img src="banner.jpg" alt="banner"/>
      <script src="app.js" type="text/javascript"></script>
      <div>
         <!-- any other code -->
      </div>
   </body>
</html>

The PushBuider instance from HttpServletRequest newPushBuilder() method is initiated with the HTTP GET method. It is implemented using a builder pattern. As a result, a chaining of the method call can be used to mutate the instance before finally calling the push() method. The push method starts a non-blocking asynchronous method and clears the path and conditional headers upon return.

Here is another code snippet to get a glimpse of how a JSF page can take advantage of Server Push.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
   Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
      xmlns_h="http://xmlns.jcp.org/jsf/html">
   <h:outputStylesheet library="css" name="style1.css"/>
   <h:outputScript library="js" name="app.js" target="head"/>
   <h:head>
      <title>Server Push JSF Demo</title>
   </h:head>
   <h:body&gt
      <h:graphicImage library="images" name="banner.jpg"/>
      <h:form>
         <!-- -->
      </h:form>
   lt;/h:body>
</html>

Conclusion

Apart from Server Push, there is another important inclusion, called the Servlet Mapping API, in Servlet 4.0. Here, we have discussed only Server Push and HTTP in its new avatar, which is actually necessary to understand and appreciate the Server Push capability. Spring framework 5.0 also supports HTTP/2 and Server Push capability with Tomcat and Jetty and will soon provide full stack support of Servlet 4.0.

References

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories