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:

Spring Boot - Unit Test Cases
Spring Boot with Multiple SQL Import Files
Java Program to Implement Sorting of Less than 100 Numbers in O(n) Complexity
Java Concurrency Interview Questions and Answers
Java Program to Implement ConcurrentLinkedQueue API
An Intro to Spring Cloud Zookeeper
Java Program to Implement Kosaraju Algorithm
Java Program to Implement Euclid GCD Algorithm
Java Program to Describe the Representation of Graph using Adjacency List
Hướng dẫn Java Design Pattern – Facade
Removing all Nulls from a List in Java
Hamcrest Collections Cookbook
Mệnh đề Switch-case trong java
Java Program to Represent Graph Using Incidence Matrix
Java Program to Find Strongly Connected Components in Graphs
Java Program to Implement Gauss Seidel Method
Java Program to Implement Bresenham Line Algorithm
Java Program to Implement Floyd Cycle Algorithm
Java Program to Implement Quick Hull Algorithm to Find Convex Hull
Spring MVC Tutorial
The XOR Operator in Java
DistinctBy in the Java Stream API
Java Program to Represent Graph Using Linked List
The Spring @Controller and @RestController Annotations
Spring Boot - Apache Kafka
Auditing with JPA, Hibernate, and Spring Data JPA
Java Program to Implement Fisher-Yates Algorithm for Array Shuffling
Tránh lỗi NullPointerException trong Java như thế nào?
Java Program to Check whether Directed Graph is Connected using DFS
Java Program to Find a Good Feedback Vertex Set
Tạo ứng dụng Java RESTful Client không sử dụng 3rd party libraries
Java Program to Implement Sorted Circularly Singly Linked List