1. 引言

HTTP/2 协议(RFC 7540)引入的服务器推送技术允许服务端主动向客户端发送资源,这与 HTTP/1.X 的被动请求模式形成鲜明对比。Spring 5 带来的新特性之一就是服务器推送支持,它基于 Jakarta EE 8 的 Servlet 4.0 API。本文将深入探讨如何在 Spring MVC 控制器中集成和使用服务器推送

2. Maven 依赖

首先定义核心依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.1.5</version>
</dependency>
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.1.0-M2</version>
    <scope>provided</scope>
</dependency>

最新版本可在 Maven Centralservlet-api 查询。

3. HTTP/2 前置条件

使用服务器推送需满足:

  • 容器支持 HTTP/2 和 Servlet 4.0 API(配置参考 Spring wiki
  • 客户端支持 HTTP/2(主流浏览器均已支持)

⚠️ 注意:若客户端不支持 HTTP/2,推送功能将自动降级为传统请求模式。

4. PushBuilder 核心特性

PushBuilder 接口是服务器推送的核心实现。在 Spring MVC 中,可直接将其注入 @RequestMapping 方法参数:

@GetMapping("/pushDemo")
public String handleRequest(PushBuilder pushBuilder) {
    // 推送逻辑
}

关键 API 说明:

  • path(String path) - 指定要推送的资源路径
  • push() - 执行推送操作
  • addHeader(String name, String value) - 为推送资源添加 HTTP 头

❌ 重要:当客户端不支持 HTTP/2 时,pushBuilder 参数将为 null,务必做空值检查。

5. 实战演示

5.1 创建 JSP 页面

创建 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 演示</title>
</head>
<body>
    <span>PushBuilder 演示页面</span>
    <br>
    <img src="<c:url value="/resources/logo.png"/>" alt="Logo" 
      height="126" width="411">
    <br>
    <!--页面内容-->
</body>
</html>

5.2 实现控制器

创建 PushController 提供两个接口对比效果:

@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";
    }
}

5.3 性能对比分析

使用 Chrome 开发者工具测试:

传统请求模式/demoWithoutPush): 传统请求模式

服务器推送模式/demoWithPush): 服务器推送模式

关键差异:

  • ✅ 推送模式下资源加载时间显著降低
  • ⚠️ 注意:推送可能增加带宽消耗(取决于推送资源数量)

优化建议

  1. 结合缓存策略(如 Spring MVC 静态资源缓存
  2. 使用资源压缩(如 Maven 资源压缩插件
  3. 部署 CDN 加速
  4. 通过性能测试确定最佳推送场景

6. 总结

本文通过实战演示了如何使用 Spring MVC 的 PushBuilder 实现服务器推送,并对比了与传统请求模式的性能差异。合理使用服务器推送能显著提升页面加载速度,但需注意带宽消耗和资源选择策略。

完整源码请参考 GitHub 仓库


原始标题:Spring 5 and Servlet 4 - The PushBuilder