«1. Введение
Технология Server Push — часть HTTP/2 (RFC 7540) — позволяет нам заранее отправлять ресурсы клиенту со стороны сервера. Это серьезное изменение по сравнению с HTTP/1.X, основанным на запросе.
Одна из новых функций Spring 5 — это поддержка push-уведомлений сервера, которая поставляется с Jakarta EE 8 Servlet 4.0 API. В этой статье мы рассмотрим, как использовать push-уведомление сервера и интегрировать его с контроллерами Spring MVC.
2. Зависимость Maven
Начнем с определения зависимостей, которые мы собираемся использовать:
<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>
Самые последние версии spring-mvc и servlet-api можно найти на Maven Central.
3. Требования HTTP/2
Чтобы использовать push-уведомление сервера, нам нужно запустить наше приложение в контейнере, который поддерживает HTTP/2 и API Servlet 4.0. Требования к конфигурации различных контейнеров можно найти здесь, в вики Spring.
Кроме того, нам потребуется поддержка HTTP/2 на стороне клиента; конечно, большинство современных браузеров имеют эту поддержку.
4. Возможности PushBuilder
Интерфейс PushBuilder отвечает за реализацию сервера push. В Spring MVC мы можем внедрить PushBuilder в качестве аргумента методов, аннотированных с помощью @RequestMapping.
На этом этапе важно учитывать, что — если клиент не поддерживает HTTP/2 — ссылка будет отправлена как нулевая.
Вот основной API, предлагаемый интерфейсом PushBuilder:
-
path (String path) — указывает ресурс, который мы собираемся отправить push() — отправляет ресурс клиенту addHeader (String имя, строковое значение) — указывает заголовок, который мы будем использовать для отправленного ресурса
5. Краткий пример
Чтобы продемонстрировать интеграцию, мы создадим страницу demo.jsp с одним ресурсом — 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>
Мы также предоставим две конечные точки с контроллером PushController — одну, которая использует push-уведомления сервера, и другую, которая не использует:
@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";
}
}
Используя инструменты разработки Chrome, мы можем увидеть различия, вызвав обе конечные точки.
Когда мы вызываем метод demoWithoutPush, представление и ресурс публикуются и потребляются клиентом с использованием технологии извлечения:
Когда мы вызываем метод demoWithPush, мы можем видеть использование push-сервера и то, как ресурс доставляется сервером заранее, что приводит к меньшему времени загрузки:
Технология push-уведомлений сервера может сократить время загрузки страниц наших приложений во многих сценариях. При этом нам нужно учитывать, что, хотя мы уменьшаем задержку, мы можем увеличить пропускную способность — в зависимости от количества обслуживаемых ресурсов.
Также рекомендуется комбинировать эту технологию с другими стратегиями, такими как кэширование, минимизация ресурсов и CDN, а также проводить тесты производительности нашего приложения, чтобы определить идеальные конечные точки для использования push-уведомлений сервера.
6. Заключение
В этом кратком руководстве мы увидели пример использования серверной технологии push с Spring MVC с использованием интерфейса PushBuilder и сравнили время загрузки при ее использовании со стандартной технологией pull.
Как всегда, исходный код доступен на GitHub.