Spring 5 and Servlet 4 – The PushBuilder

1. Introduction

The Server Push technology — part of HTTP/2 (RFC 7540) — allows us to send resources to the client proactively from the server-side. This is a major change from HTTP/1.X pull-based approach.

One of the new features that Spring 5 brings – is the server push support that comes with Jakarta EE 8 Servlet 4.0 API. In this article, we’ll explore how to use server push and integrate it with Spring MVC controllers.

2. Maven Dependency

Let’s start by defining dependencies we’re going to use:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.0</version>
    <scope>provided</scope>
</dependency>

The most recent versions of spring-mvc and servlet-api can be found on Maven Central.

3. HTTP/2 Requirements

To use server push, we’ll need to run our application in a container that supports HTTP/2 and the Servlet 4.0 API. Configuration requirements of various containers can be found here, in the Spring wiki.

Additionally, we’ll need HTTP/2 support on the client-side; of course, most current browsers do have this support.

4. PushBuilder Features

The PushBuilder interface is responsible for implementing server push. In Spring MVC, we can inject a PushBuilder as an argument of the methods annotated with @RequestMapping.

At this point, it’s important to consider that – if the client doesn’t have HTTP/2 support – the reference will be sent as null.

Here is the core API offered by the PushBuilder interface:

  • path (String path) – indicates the resource that we’re going to send
  • push() – sends the resource to the client
  • addHeader (String name, String value) – indicates the header that we’ll use for the pushed resource

5. Quick Example

To demonstrate the integration, we’ll create the demo.jsp page with one resource — logo.png:

<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>PushBuilder demo</title>
</head>
<body>
    <span>PushBuilder demo</span>
    <br>
    <img src="<c:url value="/resources/logo.png"/>" alt="Logo" 
      height="126" width="411">
    <br>
    <!--Content-->
</body>
</html>

We’ll also expose two endpoints with the PushController controller — one that uses server push and another that doesn’t:

@Controller
public class PushController {

    @GetMapping(path = "/demoWithPush")
    public String demoWithPush(PushBuilder pushBuilder) {
        if (null != pushBuilder) {
            pushBuilder.path("resources/logo.png").push();
        }
        return "demo";
    }

    @GetMapping(path = "/demoWithoutPush")
    public String demoWithoutPush() {
        return "demo";
    }
}

Using the Chrome Development tools, we can see the differences by calling both endpoints.

When we call the demoWithoutPush method, the view and the resource is published and consumed by the client using the pull technology:


When we call the demoWithPush method, we can see the use of the push server and how the resource is delivered in advance by the server, resulting in a lower load time:


The server push technology can improve the load time of the pages of our applications in many scenarios. That being said, we do need to consider that, although we decrease the latency, we can increase the bandwidth – depending on the number of resources we serve.

It’s also a good idea to combine this technology with other strategies such as Caching, Resource Minification, and CDN, and to run performance tests on our application to determine the ideal endpoints for using server push.

6. Conclusion

In this quick tutorial, we saw an example of how to use the server push technology with Spring MVC using the PushBuilder interface, and we compared the load times when using it versus the standard pull technology.

As always, the source code is available over on GitHub.

Related posts:

Java – Convert File to InputStream
Hướng dẫn sử dụng biểu thức chính quy (Regular Expression) trong Java
Java – Try with Resources
Spring @RequestParam Annotation
How to Manually Authenticate User with Spring Security
Java Program to Implement Interval Tree
Mệnh đề Switch-case trong java
Java Program to Perform Searching in a 2-Dimension K-D Tree
Java Program to Perform Sorting Using B-Tree
Giới thiệu Swagger – Công cụ document cho RESTfull APIs
Java Program to Find the Connected Components of an UnDirected Graph
Java – Reader to String
Spring Boot - Tomcat Port Number
Spring Boot - Building RESTful Web Services
Using JWT with Spring Security OAuth (legacy stack)
Java Program to Implement Double Ended Queue
Iterable to Stream in Java
Java Program to Check Whether an Undirected Graph Contains a Eulerian Path
How to Remove the Last Character of a String?
Guide to the Java TransferQueue
Unsatisfied Dependency in Spring
Java Program to Solve any Linear Equations
Java Program to Check Whether a Weak Link i.e. Articulation Vertex Exists in a Graph
Java Program to Implement Heap Sort Using Library Functions
Spring Security Remember Me
Java Program to Implement Fisher-Yates Algorithm for Array Shuffling
Use Liquibase to Safely Evolve Your Database Schema
Java Program to Print only Odd Numbered Levels of a Tree
Tính đa hình (Polymorphism) trong Java
Java 8 Stream API Analogies in Kotlin
Spring Cloud AWS – RDS
Java Program to Generate All Possible Combinations of a Given List of Numbers