【Spring Boot官方文档原文理解翻译-持续更新中】

【Spring Boot官方文档原文理解翻译-持续更新中】

文章目录

  • 【Spring Boot官方文档原文理解翻译-持续更新中】
  • Chapter 4. Getting Started
    • 4.1. Introducing Spring Boot
    • 4.2. System Requirements
      • 4.2.1. Servlet Containers
    • 4.3. Installing Spring Boot
      • 4.3.1. Installation Instructions for the Java Developer
        • 4.3.1.1. Maven Installation
      • 4.3.2. Installing the Spring Boot CLI
        • Manual Installation
        • Installation with SDKMAN!
        • OSX Homebrew Installation
        • Command-line Completion
    • 4.4. Developing Your First Spring Boot Application
  • Chapter 6. Developing with Spring Boot
    • 6.1. Build Systems
      • 6.1.1. Dependency Management
      • 6.1.2. Maven
      • 6.1.3. Gradle
      • 6.1.4. Ant
      • 6.1.5. Starters
    • 6.2. Structuring Your Code
      • 6.2.1. Using the “default” Package
      • 6.2.2. Locating the Main Application Class
    • 6.3. Configuration Classes
      • 6.3.1. Importing Additional Configuration Classes
      • 6.3.2. Importing XML Configuration
    • 6.4. Auto-configuration
      • 6.4.1. Gradually Replacing Auto-configuration
      • 6.4.2. Disabling Specific Auto-configuration Classes
    • 6.6. Using the @SpringBootApplication Annotation
  • Chapter 7. Core Features
      • 7.4.6. Log Groups
    • 7.6. JSON
      • 7.6.1. Jackson
        • Custom Serializers and Deserializers
  • Chapter 8. Web
    • 8.1. Servlet Web Applications
      • 8.1.1. The “Spring Web MVC Framework”
        • Spring MVC Auto-configuration
        • HttpMessageConverters
        • MessageCodesResolver
        • Static Content
        • Welcome Page
        • Custom Favicon
        • Path Matching and Content Negotiation
        • ConfigurableWebBindingInitializer
        • Template Engines
        • Error Handling
          • Custom Error Pages
      • 8.1.2. JAX-RS and Jersey
      • 8.1.3. Embedded Servlet Container Support
        • Servlets, Filters, and listeners
        • Servlet Context Initialization
        • The ServletWebServerApplicationContext
        • Customizing Embedded Servlet Containers
          • Customizing ConfigurableServletWebServerFactory Directly
          • JSP Limitations
    • 8.2. Reactive Web Applications
      • 8.2.1. The “Spring WebFlux Framework”
        • Spring WebFlux Auto-configuration
        • HTTP Codecs with HttpMessageReaders and HttpMessageWriters
        • Static Content
        • Welcome Page
        • Template Engines
        • Error Handling
  • Chapter 13. Production-ready Features
        • Spring MVC Metrics
  • Chapter 14. Deploying Spring Boot Applications
    • 14.2. Installing Spring Boot Applications
  • Chapter 17. “How-to” Guides
    • 17.1. Spring Boot Application
    • 17.3. Embedded Web Servers
      • 17.3.1. Use Another Web Server
      • 17.3.7. Configure SSL
      • 17.3.6. Enable HTTP Response Compression
      • 17.3.11. Configure Access Logging
      • 17.7.2. Configure Log4j for Logging
      • 17.16.9. Build an Executable Archive from Ant without Using spring-boot-antlib
  • Appendices
    • Appendix A: Common Application Properties
      • A.11. Server Properties

Chapter 4. Getting Started

  如果您想入门 Spring Boot 或是 Spring,那么就从阅读这一部分开始吧。它会回答这些基础的 “是什么?”、“怎么做?” 和 “ 为什么?” 这类问题,并且包含了 Spring Boot 的详细介绍和使用说明。稍后我们将指导您搭建第一个 Spring Boot 应用,并且谈论一些其中的核心原则。
 

4.1. Introducing Spring Boot

  Spring Boot 帮助您创建一个单例的、生产级的且基于 Spring 的应用程序。因为我们对 Spring 平台和第三方库保持中立,所以您可以以最少的麻烦上手 (Spring Boot),大多数的 Spring Boot 应用程序甚至只需要很少的 (近乎没有的) Spring 配置。

  Spring Boot 可以创建 Java 应用程序,这些程序通过 java -jar 命令或者传统 war 包依赖启动,而且 (为了方便) 我们还提供了一个运行 “ spring scripts (spring 脚本)” 的命令行工具。

 

我们的主要目标是

  • 致力于为所有 Spring 的开发者提供更快速、可广泛访问的入门体验
  • 保持开箱即用,虽然随着需求开始会偏离默认值但是会迅速摆脱困境
  • 提供一系列非功能性的特性,且通常是大类别的项目(例如内置服务器、安全、度量、运行状况检查和外部化配置)
  • 无任何代码生成并且不需要 XML 配置
     

4.2. System Requirements

Spring Boot 2.7.2 版本至少需要 Java 8 且兼容包含 Java 18 在内的更高JDK版本,Spring Framework 5.3.22 (或更高版本) 也需要。

为下列搭建工具提供了显式支持:

搭建工具 版本
Maven 3.5+
Gradle 6.8.x, 6.9.x, 和 7.x

 

4.2.1. Servlet Containers

Spring Boot 支持下列嵌入式的 servlet 容器:

Servlet 容器名称 Servlet 版本
Tomcat 9.0 4.0
Jetty 9.4 3.1
Jetty 10.0 4.0
Undertow 2.0 4.0

而且,也可以把 Spring Boot 应用部署在任何兼容 servlet 3.1+ 版本的容器中

 

4.3. Installing Spring Boot

  Spring Boot 可与 “ classic ” 这种 Java 开发工具一起使用或者作为命令行工具安装。如果不想使用前面的两种方式也没关系,您只需要有 Java SDK v1.8 或更高版本即可。此外,在开始使用之前,您应该先使用下列命令检查电脑当前安装的 Java 版本

$ java -version

  如果您是 Java 开发菜鸟或者只是想浅尝辄止,最好先试试 Spring Boot CLI (Spring Boot 命令行接口),而且需要先阅读 “ classic ” 的安装指导。

 

4.3.1. Installation Instructions for the Java Developer

  您可以像使用任何 Java 标准库那样使用 Spring Boot,为此请引入对应版本的 spring-boot-*.jar 文件到类路径下。Spring Boot 不需要任何指定的集成工具,所以可以使用任何 IDE(全称是Intergration Development Environment,意为集成开发环境)或者编辑器进行软件开发。此外,Spring Boot 平平无奇,所以我们可以像运行其他的 Java 程序一样去运行和调试 Spring Boot 应用程序。

  虽然独立的 Spring jar 包也可以进行开发,但是通常建议使用支持依赖管理的搭建工具(例如 Maven 或者 Gradle),因为这样管理起来更方便
 

4.3.1.1. Maven Installation

  Spring Boot 兼容 Apache Maven 3.3+ 版本。如果您还没有安装 Maven 的话,建议按照 maven.apache.org 站点上的说明进行安装配置。

 

小贴士

  大多数的操作系统上,Maven 会与包管理器进行捆绑安装。如果使用 OSX Homebrew 包管理器的话,尝试运行 brew install maven 命令安装 Maven,Ubuntu 用户运行 sudo apt-get install maven 命令也可以安装 Maven。而带有 Chocolatey 软件的 Windows 用户则可以从高级(管理员)提示符中运行 choco install maven 安装 Maven

 
  Spring Boot 依赖使用 org.springframework.boot.groupId 作为组织名。按照惯例,Maven 的 POM 文件继承 spring-boot-starter-parent 项目的同时会声明一个或多个 “ 启动器 ” 的依赖。不过 Spring Boot 自身也提供了可选的 Maven 插件来创建可执行的 jar 包。

 

4.3.2. Installing the Spring Boot CLI

  Spring Boot CLI (Command Line Interface:命令行接口) 是一个命令行工具,可快速开发 Spring 原型。并且它可以运行 Groovy 脚本,这意味着只需很少的样板代码就可以进行快速开发,因为您熟悉 Java 语法。

  虽然不一定需要通过 CLI 使用 Spring Boot,但是它也是一个快捷的方法,让您不需要 IDE 也可以脱离后台获取 Spring 应用。
 

Manual Installation

Spring CLI 正式版本在 Spring 软件仓库下载:

  • spring-boot-cli-2.7.2-bin.zip

  • spring-boot-cli-2.7.2-bin.tar.gz

此外,(如果有需要的话) 这个仓库还提供最新的快照版本,下载后,按照 INSTALL.txt 指导文件从解压缩开始操作。
  综上所述,这是一个 .zip 文件 bin/ 目录下的 spring 脚本(spring.bat 用于 Windows操作系统 )。此外, java -jar 命令可以与 .jar 文件混用(脚本有助于设置正确的 classpath 目录)

 

Installation with SDKMAN!

SDKMAN! (软件开发工具管理员) 用于管理多个版本的各种二进制软件开发工具包,其中包含 Groovy 和 Spring Boot CLI,(如果我们想利用SDKMAN安装SpringBoot) 可以从 sdkman.io 站点中获取 SDKMAN 并且使用下面的命令安装它:

$ sdk install springboot
$ spring --version
Spring CLI v2.7.2

如果想为 CLI 开发功能并且想要访问自己构建的版本,那么请使用下面的命令:

$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-bootcli-2.7.2-bin/spring-2.7.2/
$ sdk default springboot dev
$ spring --version
Spring CLI v2.7.2

前面的指导会安装一个名为 dev 的本地 spring 实例。此外它会指向搭建的目标位置,所以每次重构 Spring Boot 时,Spring 的版本都是最新的。

运行下列命令查看:

$ sdk ls springboot
================================================================================
Available Springboot Versions
================================================================================
> + dev
* 2.7.2
================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

 

OSX Homebrew Installation

如果在 Mac 上使用 HomeBrew,使用下列命令安装 Spring Boot CLI:

$ brew tap spring-io/tap
$ brew install spring-boot

Homebrew 会将 spring 安装到 /usr/local/bin 目录上。

注意

  如果您没有看到公式,那么安装的 brew 可能已经过时。在这种情况下,应该运行 brew update 升级它并且再试一次。

 

Command-line Completion

  Spring Boot CLI 包含 BASH 和 zsh 的 shell 命令脚本,您可以在任何shell 中使用 source 命令脚本(也叫spring)或者…
 

4.4. Developing Your First Spring Boot Application

 

Chapter 6. Developing with Spring Boot

  本章将会更加详细地介绍如何正确使用 Spring Boot,覆盖了类似于系统搭建、自动配置和如何运行应用程序的话题。除此之外,也包含了一些 (使用) Spring Boot 最佳实践。虽然 Spring Boot 平平无奇 (只不过就是另一个您可以使用的库),但是下面的一些建议,可以让开发的过程变得更简单。

  如果是从 Spring Boot 才开始的 (指跳过了 Spring 直接学习 Spring Boot),那么建议您在阅读这一章前先阅读 入门 指导。

 

6.1. Build Systems

  强烈建议选择支持 依赖管理 并且可以发布到 “ Maven Central ” 仓库(Maven 中心仓库)的依赖自动化搭建系统,最好是 Maven 或者 Gradle。当然也可以让 Spring Boot 与其他的自动化搭建系统一起工作(例如:Ant),不过对比前面两种,我们对其他的支持力度不大。
 

6.1.1. Dependency Management

  所有的 Spring Boot 的正式版本都提供了它所支持的一个依赖管理列表。在开发中,不需要为这些依赖手动提供版本号,Spring Boot 将自动管理。当 Spring Boot 更新升级时,这些依赖也会同时进行更新升级。
 

注意

  如果需要的话,可以手动指定某个依赖的版本号并且覆盖 Spring Boot 推荐的。

  依赖管理列表包含了所有可以和 Spring 模块一起使用的第三方库的依赖细化列表。这个列表可以作为一个标准的材料清单 (spring-boot dependencies),用于 Maven 或者 Gradle

警告

  所有的 Spring Boot 的正式版本都与 Spring 框架的一个基础版本相关联,强烈建议不要手动指定其版本号

 

6.1.2. Maven

要了解如何使用 Spring Boot 与 Maven,请查阅 Spring Boot 的 Maven 插件文档:

  • 参考链接 (HTML 和 PDF)

  • API文档
     

6.1.3. Gradle

要了解如何使用 Spring Boot 与 Gradle,请查阅 Spring Boot 的 Gradle 插件文档:

  • 参考链接 (HTML 和 PDF)

  • API文档

 

6.1.4. Ant

  搭建 Spring Boot 项目可以使用 Apache 的 Ant + lvy。spring-boot-antlib模块也有助于 Ant 创建可执行的 jar 包。

典型的声明依赖关系的 ivy.xml 文件如下所示:

<ivy-module version="2.0">
    <info organisation="org.springframework.boot" module="spring-boot-sample-ant" />
    <configurations>
        <conf name="compile" description="everything needed to compile this module" />
        <conf name="runtime" extends="compile" description="everything needed to run
                                                            this module" />
    configurations>
    <dependencies>
        <dependency org="org.springframework.boot" name="spring-boot-starter"
                    rev="${spring-boot.version}" conf="compile" />
    dependencies>
ivy-module>

典型的 build.xml 文件如下所示:

<project
         xmlns:ivy="antlib:org.apache.ivy.ant"
         xmlns:spring-boot="antlib:org.springframework.boot.ant"
         name="myapp" default="build">
    <property name="spring-boot.version" value="2.7.2" />
    <target name="resolve" description="--> retrieve dependencies with ivy">
        <ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
    target>
    <target name="classpaths" depends="resolve">
        <path id="compile.classpath">
            <fileset dir="lib/compile" includes="*.jar" />
        path>
    target>
    <target name="init" depends="classpaths">
        <mkdir dir="build/classes" />
    target>
    <target name="compile" depends="init" description="compile">
        <javac srcdir="src/main/java" destdir="build/classes"
               classpathref="compile.classpath" />
    target>
    <target name="build" depends="compile">
        <spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
            <spring-boot:lib>
                <fileset dir="lib/runtime" />
            spring-boot:lib>
        spring-boot:exejar>
    target>
project>

 

小贴士

  如果不希望使用 spring-boot-antlib 模块,请查看 How-to Guides 中的 Build an Executable Archive from Ant without Using spring-boot-antlib 这一章节

 

6.1.5. Starters

  启动器是一套便捷的依赖描述符,可以将其引入到应用程序中。有了启动器,就获得了所有 Spring 和其相关技术的一站式服务,不需要亲自查找示例代码并且复制粘贴大量的依赖描述符。例如,如果想要使用 Spring 与 JPA 访问数据库,可以在项目中包含 spring-boot-starter-data-jpa 启动器。

  启动器包含许多快速启动以及运行项目所需的依赖,并且相互之间具有一致的、受支持的托管依赖传递关系。

在名称里的东西是什么?

  所有的官方启动器都遵循一个类似的命名模板: spring-boot-starter-** 是一个独特的应用类型。这种命名结构旨在当需要找到启动器时提供帮助。大部分的 IDE 中集成的 Maven 允许按名称查找依赖,例如,安装了合适的 Eclipse 或者是 Spring Tools 插件后,在 POM 编辑器中按 ctrl + space 键入“ spring-boot-starter ” 可以获得完整的依赖列表。

  正如 “ Creating Your Own Starter ” (创造自己的启动器)所言,第三方启动器不应该以 spring-boot 开头,因为这是为 Spring Boot 官方依赖所保留的。不过,一个第三方启动器常常会以项目的名称作为开头(所以一般不用担心)。比如,一个叫做 thirdpartproject 的第三方项目将会毫无疑问地以 thirdpartproject-spring-boot-starter 命名

 
Spring Boot的 org.springframework.boot 分组提供下列应用启动器:

表1.Spring Boot 应用启动器

名称 简要描述
spring-boot-starter Spring Boot 的核心启动器,包含自动配置支持,日志记录和 YAML
spring-boot-starter-activemq JMS(Java消息服务:是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。)使用 Apache 的 ActiveMQ消息队列发送消息的启动器
spring-boot-starter-amqp Spring 的 AMQP(AMQP:即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议)和Rabbit MQ(RabbitMQ:这是一个开源消息代理软件。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。)的启动器
spring-boot-starter-aop Spring AOP 切面方向的编程和 AspectJ 的启动器
spring-boot-starter-artemis JMS 使用 Apache 的 Artemis 的启动器
spring-boot-starter-batch Spring 批处理任务的启动器
spring-boot-starter-cache Spring 框架缓存支持的启动器
spring-boot-starter-data-cassandra Cassandra 分布式数据库(Cassandra:是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩展性,被Digg、Twitter等知名[Web 2.0](https://baike.baidu.com/item/Web 2.0)网站所采纳,成为了一种流行的分布式结构化数据存储方案。)和 String Data Cassandra 的启动器
spring-boot-starter-data-cassandra-reactive Cassandra 分布式数据库和 String Data Cassandra Reactive 的启动器
spring-boot-starter-data-couchbase 使用 Couchbase 面向文档数据库(CouchBase:是一款开源的、分布式的、面向文档的NoSQL数据库,主要用于分布式缓存和数据存储领域。能够通过manage cache提供快速的亚毫米级别的k-v存储操作,并且提供快速的查询和其功能强大的能够指定SQL-like查询的查询引擎。)和 Spring Data Couchbase 的启动器
spring-boot-starter-data-couchbase-reactive Cassandra 分布式数据库和 String Data Cassandra Reactive 的启动器
spring-boot-starter-data-elasticsearch Elasticsearch 搜索(Elasticsearch:是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和分享对数据的见解,并管理和监控堆栈。Elasticsearch 是索引、搜索和分析魔法发生的地方。)、分析引擎和Spring Data Elasticsearch的启动器
spring-boot-starter-data-jdbc Spring Data JDBC(JDBC:全称Java Database Connectivity,也即Java数据库连接,简称JDBC。它是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。)的启动器
spring-boot-starter-data-jpa Spring Data JPA(JPA:JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。)与Hibernate(Hibernate:是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JavaEE架构中取代CMP,完成数据持久化的重任。)的启动器
spring-boot-starter-data-ldap Spring Data LDAP(LDAP:全称Lightweight Directory Access Protocol, 意为轻型目录访问协议,它是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的目录信息。)的启动器
spring-boot-starter-data-mongodb MongoDB 面向文档数据库(MongoDB:是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。)和 Spring Data MongoDB 的启动器
spring-boot-starter-data-mongodb-reactive MongoDB 面向文档数据库和 Spring Data MongoDB Reactive 的启动器
spring-boot-starter-data-neo4j Neo4j 图形数据库(Neo4j:是一个高性能的,NOSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。)和 Spring Data Neo4j 的启动器
spring-boot-starter-data-r2dbc Spring Data R2DBC 的启动器
spring-boot-starter-data-redis Spring Data Redis 存储 Redis 键值对与和 Lettuce client 的启动器
spring-boot-starter-data-redis-reactive Spring Data Redis reactive 存储 Redis 键值对和 Lettuce client 的启动器
spring-boot-starter-data-rest 用于 Spring Data REST 在 Rest 上公开 Spring Data 仓库的启动器
spring-boot-starter-freemarker 使用FreeMarker视图(FreeMarker:是一款模板引擎, 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网络、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。)搭建MVC网络应用而生的启动器
spring-boot-starter-graphql Spring GraphQL搭建GraphQL应用的启动器
spring-boot-starter-groovy-templates 用于 Groovy 模板视图(Groovy:是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与 Java 代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy也可以使用其他非Java语言编写的库。)搭建 MVC 网络应用的启动器
spring-boot-starter-hateoas Spring MVC 搭建基于超媒体和 Restful 风格的网络应用和 Spring HATEOAS 的启动器
spring-boot-starter-integration Spring Integration 的启动器
spring-boot-starter-jdbc HikariCP连接池使用 JDBC 的启动器
spring-boot-starter-jersey 用 JAX-RS 和 Jersey 搭建 Restful 风格的网络应用的启动器。此外,也可以选用spring-boot-starter-web
spring-boot-starter-jooq JDBC 使用 jOOQ 访问 SQL 数据库的启动器。此外,也可以选用 spring-bootstarter-data-jpa 或者是spring-boot-starter-jdbc
spring-boot-starter-json 读写 JSON(JSON:全称JavaScript Object Notation, JS对象简谱,这是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。)的启动器
spring-boot-starter-jta-atomikos JTA 事务(JTA:即Java Transaction API,JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。)使用 Atomikos(Atomikos: 是一个为Java平台提供增值服务的并且开源类事务管理器。)的启动器
spring-boot-starter-mail Java 和 Spring 框架的邮件发送支持的启动器
spring-boot-starter-mustache Mustache 视图搭建网络应用的启动器
spring-boot-starter-oauth2-client Spring Security 的 OAuth2(OAuth2:是一种授权框架,提供了一套详细的授权机制(指导)。用户或应用可以通过公开的或私有的设置,授权第三方应用访问特定资源。)或 OpenID 连接客户端特性使用的启动器
spring-boot-starter-oauth2-resource-server Spring Security 的 OAuth2 资源服务器特性使用的启动器
spring-boot-starter-quartz Spring Quartz 的启动器
spring-boot-starter-rsocket 搭建 RSocket 客户端和服务器的启动器
spring-boot-starter-security Spring Security 的启动器
spring-boot-starter-test 使用包含 JUnit Jupiter、Hamcrest 和 Mockito 的依赖代码库测试 Spring Boot 应用的启动器
spring-boot-starter-thymeleaf Thymeleaf 视图搭建 MVC 网络应用的启动器
spring-boot-starter-validation Java Bean 验证与 Hibernate 验证器的启动器
spring-boot-starter-web Spring MVC搭建包含Restful风格的网络应用的启动器。使用Tomcat作为默认嵌入式容器
spring-boot-starter-web-services Spring 网络服务的启动器
spring-boot-starter-webflux Spring 框架的 Reactive 网络支持搭建 WebFlux 应用的启动器
spring-boot-starter-websocket Spring 框架的 WebSocket 支持搭建 WebSocket 应用的启动器

除了上面提到的应用启动器,下列启动器常常用于添加 生产就绪 特性:

表2.Spring Boot生产启动器

名称 简要描述
spring-boot-starter-actuator 使用Spring Boot的Actuator提供生产就绪特性帮助监督和管理您的应用的启动器

最后,Spring Boot还包含了以下启动器,如果您想排除或者更换指定技术面的话会用到:

表3.Spring Boot技术启动器

名称 简要描述
spring-boot-starter-jetty 使用Jetty作为内置的servlet容器的启动器,也可选用spring-boot-starter-tomcat启动器
spring-boot-starter-log4j2 使用Log4j2的日志记录的启动器,也可选用spring-boot-starter-logging启动器
spring-boot-starter-logging 使用Logback记录日志的启动器,它也是Spring默认日志记录启动器
spring-boot-starter-reactor-netty 使用Reactor Netty作为内置的reactive HTTP 服务器的启动器
spring-boot-starter-tomcat 使用Tomcat作为内置的servlet容器的启动器,也是spring-boot-starter-web中使用的默认servlet容器启动器
spring-boot-starter-undertow 使用Undertow(Undertow:是一个采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制。Undertow 是红帽公司的开源产品,是 Wildfly 默认的 Web 服务器。)作为内置servlet容器的启动器,也可选用spring-boot-starter-tomcat启动器

要了解如何更换技术面,请查看 swapping web serverlogging system 文档

 

小贴士

  对于社区贡献的启动器列表,可以查看 Github上 的 spring-boot-starters 模块中的 README 文件

 

6.2. Structuring Your Code

  Spring Boot 不需要使用任何指定的布局代码来工作,不过也有些最佳实践是有所帮助的。
 

6.2.1. Using the “default” Package

  当一个类不包含 package 关键字的声明,它被认为在 “ 默认包 ” 下。这种 “ 默认包 ” 的使用通常是不被鼓励且应该摒弃的。在 Spring Boot 使用 @ComponentScan@ConfigurationPropertiesScan@EntityScan 、或者是@SpringBootApplication 注解的时候, 它会引起奇怪的 BUG,因为每个 jar 包里的类都是可读的

小贴士

  建议遵守 Java 的推荐包命名规范且使用反向域名(例如:com.example.project

 

6.2.2. Locating the Main Application Class

  我们通常推荐在其他类上面的根路径包中查找主应用类。 @SpringBootApplication 注解 常常用于放置在主类上,并且暗中为某些项目定义了一个基础的 “ 搜索包 ” 。例如,如果您编写一个 JPA 应用,@SpringBootApplication 注释的包将用于定位 @Entity 注解项。此外,使用根路径包也允许组件扫描仅用于项目。

 

小贴士

  如果不想使用 @SpringBootApplication 注解, 它导入的 @EnableAutoConfiguration@ComponentScan 注解也定义了那些行为(这里的行为指的是组件扫描,自动配置等功能),换成这两个注解也是可行的

 

下面的示例代码展示了一个典型的布局:

com
 +- example
  +- myapplication
  +- MyApplication.java
  |
  +- customer
  | +- Customer.java
  | +- CustomerController.java
  | +- CustomerService.java
  | +- CustomerRepository.java
  |
  +- order
  +- Order.java
  +- OrderController.java
  +- OrderService.java
  +- OrderRepository.java

MyApplication.java文件将会声明main方法,以及基本的 @SpringBootApplication 注解,如下所示:

Java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
    
}

Kotlin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

 

6.3. Configuration Classes

  Spring Boot 偏爱基于 Java 的配置,虽然 XML 文件源也可以使用 SpringApplication,但是我们通常建议您的主要来源应当是一个独立的 @Configuration 类。通常来说,定义 main 方法的类是一个合格的 @Configuration 的候选者
 

6.3.1. Importing Additional Configuration Classes

  您不需要把所有的 @Configuration 放在一个独立的类中,比如 @Import 注解常常用于导入其他的配置类。此外,您还可以使用 @ComponentScan 注解,它会自动装配所有包含 @Configuration 注解的类将其作为 Spring 的组件。
 

6.3.2. Importing XML Configuration

  如果您必须使用基于 XML 的配置,那么我们也建议您先从 @Configuration 类开始,然后再使用 @ImportResource 注解加载 XML 配置文件。
 

6.4. Auto-configuration

  Spring Boot 自动配置基于添加的 jar 包依赖自动构建 Spring 应用程序。例如:如果 HSQLDB (Hyper SQL Database) 在类路径下,并且没有手动配置任何数据库连接的 bean,那么 Spring Boot 自动配置一个在内存中的数据库。

  通过往某一个 @Configuration 配置类中添加 @EnableAutoConfiguration 或者 @SpringBootApplication 注解来选择使用自动配置。

小贴士

  您应该只添加一个 @SpringBootApplication 或者 @EnableAutoConfiguration 注解,通常建议只将某一个添加到您的 @Configuration 配置类中

 

6.4.1. Gradually Replacing Auto-configuration

  自动配置是非侵入式的,在任何时候,都可以使用自定义配置更换特定的自动配置。例如:如果您添加自定义的 DataSource 的 bean,那么默认内置的数据库就会失效。
  如果需要了解当前应用的自动配置及其详情,打开应用程序 --debug 开关,这样做可以启用核心日志器进行日志调试并且将情况输出到控制台。
 

6.4.2. Disabling Specific Auto-configuration Classes

  如果发现应用程序中有不需要的自动配置类,可以使用 @SpringBootAplication 注解的 exclude 属性来禁用他们,如下所示:

Java

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {
}

Kotlin

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
class MyApplication

  如果该类不在当前类的类路径下,还可以使用 excludeName 属性指定类的全限定名。如果您更偏爱 @EnableAutoConfiguration 而不是 @SpringBootApplication 注解, excludeexcludeName 属性也能使用。顺便一提,使用 spring.autoconfigure.exclude 属性,还能排除自动配置类的列表

小贴士

  您可以通过注解级别以及使用属性定义排除项

注意

  虽然自动配置类是 public 的,但是这些 API 的公共部分仅用于禁用自动配置类。这些类的实际内容,类似于嵌套配置类或者只供内部使用的 bean 方法所以我们不推荐直接使用这些。

 

6.6. Using the @SpringBootApplication Annotation

 

Chapter 7. Core Features

 

7.4.6. Log Groups

 

7.6. JSON

 

7.6.1. Jackson

 

Custom Serializers and Deserializers

 

Chapter 8. Web

  因为 Spring Boot 非常适合网络应用开发,所以您可以使用内置的 Tomcat、Jetty、Undertow 或 Netty 创建独立的 HTTP 服务器。虽然大多数的网络应用使用 spring-boot-starter-web 模块快速启动和运行,但是您也可以选择使用 spring-boot-starter-webflux 模块搭建 reactive 网络应用。

  如果您还没有开发过 Spring Boot 网络应用,可以按照 Getting started 章节中的示例进行开发。
 

8.1. Servlet Web Applications

  如果想搭建基于 servlet 的网络应用,您可以利用 Spring Boot 的 Spring MVC 或 Jersey 的自动配置实现
 

8.1.1. The “Spring Web MVC Framework”

  Spring Web MVC framework(通常被称为 “ Spring MVC ”)是一个强大的 “ model view controller (模型-视图-控制器)” 的网络框架。Spring MVC 可以让您创建特殊的 @Controller@RestController 的 bean 处理接收的 HTTP 请求,在控制器中的方法使用 @RequestMapping 注解映射 HTTP 请求。

下列代码展示了提供 JSON 数据的典型 @RestController

Java

import java.util.List;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/users")
public class MyRestController {

    private final UserRepository userRepository;

    private final CustomerRepository customerRepository;

    public MyRestController(UserRepository userRepository, CustomerRepository
                            customerRepository) {
        this.userRepository = userRepository;
        this.customerRepository = customerRepository;
    }

    @GetMapping("/{userId}")
    public User getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId).get();
    }

    @GetMapping("/{userId}/customers")
    public List<Customer> getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
    }

    @DeleteMapping("/{userId}")
    public void deleteUser(@PathVariable Long userId) {
        this.userRepository.deleteById(userId);
    }
    
}

Kotlin

import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/users")
class MyRestController(private val userRepository: UserRepository, private val
customerRepository: CustomerRepository) {

    @GetMapping("/{userId}")
    fun getUser(@PathVariable userId: Long): User {
        return userRepository.findById(userId).get()
    }

    @GetMapping("/{userId}/customers")
    fun getUserCustomers(@PathVariable userId: Long): List<Customer> {
        return
        userRepository.findById(userId).map(customerRepository::findByUser).get()
    }

    @DeleteMapping("/{userId}")
    fun deleteUser(@PathVariable userId: Long) {
        userRepository.deleteById(userId)
    }
    
}

“ WebMvc.fn ” 就是功能变体,从实际的请求处理中分离路由配置,如下所示:

Java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;

import static org.springframework.web.servlet.function.RequestPredicates.accept;
import static org.springframework.web.servlet.function.RouterFunctions.route;

@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {
      
    private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);
    
    @Bean
    public RouterFunction<ServerResponse> routerFunction(MyUserHandler userHandler) {
        return route()
            .GET("/{user}", ACCEPT_JSON, userHandler::getUser)
            .GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
            .DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
            .build();
    }
}

Kotlin

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

import org.springframework.http.MediaType

import org.springframework.web.servlet.function.RequestPredicates.accept
import org.springframework.web.servlet.function.RouterFunction
import org.springframework.web.servlet.function.RouterFunctions
import org.springframework.web.servlet.function.ServerResponse

@Configuration(proxyBeanMethods = false)
class MyRoutingConfiguration {
    
    @Bean
    fun routerFunction(userHandler: MyUserHandler): RouterFunction<ServerResponse> {
        return RouterFunctions.route()
        .GET("/{user}", ACCEPT_JSON, userHandler::getUser)
        .GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
        .DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
        .build()
    }
    
    companion object {
        private val ACCEPT_JSON = accept(MediaType.APPLICATION_JSON)
    }
    
}

Java

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.function.ServerRequest;
import org.springframework.web.servlet.function.ServerResponse;

@Component
public class MyUserHandler {
    
    public ServerResponse getUser(ServerRequest request) {
        ...
    	return ServerResponse.ok().build();
    }
    
    public ServerResponse getUserCustomers(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }
    
    public ServerResponse deleteUser(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }
    
}

Kotlin

import org.springframework.stereotype.Component

import org.springframework.web.servlet.function.ServerRequest
import org.springframework.web.servlet.function.ServerResponse

@Component
class MyUserHandler {
    
    fun getUser(request: ServerRequest?): ServerResponse {
        return ServerResponse.ok().build()
    }
    
    fun getUserCustomers(request: ServerRequest?): ServerResponse {
        return ServerResponse.ok().build()
    }
    
    fun deleteUser(request: ServerRequest?): ServerResponse {
        return ServerResponse.ok().build()
    }
    
}

  Spring MVC 是 Spring 核心框架的一部分,详情信息可以在 参考文档 中获取。此外,在 spring.io/guides 中的一些指南也有提及。

小贴士
  您可以以模块化路由器的定义来定义任意数量 RounterFunction 的 bean,如果需要应用优先级可以对 bean 进行排序。

 

Spring MVC Auto-configuration

  Spring Boot 为 Spring MVC 提供适用于大多数应用程序的自动配置

  自动配置基于Spring的默认值添加下列功能:

  • 包含 ContentNegotiatingViewResolverBeanNameViewResolver 的 bean

  • 支持静态资源服务,包括WebJars(后面的章节 将会介绍到)

  • CoverterGenericConverterFormatter 的 bean 自动注册

  • 支持 HttpMessageConverters后面的章节 将会介绍到)

  • MessageCodesResolver 的自动注册(后面的章节 将会介绍到)

  • 静态 index.html 支持

  • 自动使用 ConfigurableWebBindingInitializer 的 bean(后面的章节 将会介绍到)

  如果想要保留这些自定义的 Spring Boot MVC 功能并且获取更多(例如:拦截器,格式化器,视图控制器以及其他),可以添加自己的 WebMvcConfiugurer 类型的@Configurarion 配置类,@EnableWebMvc 配置的会自动移除。

  如果需要提供定制的 RequestMappingHandlerMappingRequestMappingHandlerAdapterExceptionHandlerExceptionResolver 的实例,并且始终保留自定义的 Spring Boot MVC 功能,那么您需要声明一个 WebMvcRegistrations 类型的 bean ,并且使用它来提供这些定制组件的实例。

  如果您想完全控制 Spring MVC,可以使用 @EnableWebMvc 注解并添加自定义的 @Configuration 配置类,或者直接添加一个自定义的 @Configuration 配置类,就像@EnableWebMvc 的 Javadoc 中描述的 @DelegatingWebMvcConfiguration 一样。

注意

  Spring MVC 使用不同的 ConversionService ,他们从application.propertiesapplication.yaml 配置文件中读取并转换值。这意味着 PeriodDurationDataSize 不可用且 @DurationUnit@DataSizeUnit 注解将会被忽略。

  如果需要自定义 Spring MVC 使用的 ConversionService,只要提供一个带 addFormatters 方法的 WebMvcConfigurer 的 bean 即可。在这个方法中,可以注册任何喜欢的转换器,也可以托管给 ApplicationConversionService 类提供的静态方法。

 

HttpMessageConverters

  Spring MVC 使用 HttpMessageConverter 接口转换 HTTP 请求和响应,所以合理的默认值可以做到开箱即用的,例如,对象可以自动转为 JSON(使用 Jackson 库)或 XML(如果 Jackson 的 XML 扩展可用的话,使用 Jackson 的 XML 扩展,否则使用 JAXB)。在默认情况下,String 使用 UTF-8 编码。

  如果您需要添加或自定义转换器,推荐使用 Spring Boot 的 HttpMessageConverters 类,如下所示:

Java

import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;

@Configuration(proxyBeanMethods = false)
public class MyHttpMessageConvertersConfiguration {
    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();
        HttpMessageConverter<?> another = new AnotherHttpMessageConverter();
        return new HttpMessageConverters(additional, another);
    }
}

Kotlin

import org.springframework.boot.autoconfigure.http.HttpMessageConverters
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.HttpMessageConverter

@Configuration(proxyBeanMethods = false)
class MyHttpMessageConvertersConfiguration {
    @Bean
    fun customConverters(): HttpMessageConverters {
        val additional: HttpMessageConverter<*> = AdditionalHttpMessageConverter()
        val another: HttpMessageConverter<*> = AnotherHttpMessageConverter()
        return HttpMessageConverters(additional, another)
    }
}

  所有存在于上下文中的 HttpMessageConverter 的 bean 都添加到转换器列表中,以相同的方式可以重写默认的转换器。
 

MessageCodesResolver

  Spring MVC 有一个默认消息处理策略,从绑定错误:MessageCodesResolver 中翻译错误信息并生成错误码。如果设置了 spring.mvc.message-codes-resolver-format 属性的值为 PREFIX_ERROR_CODEPOSTFIX_ERROR_CODE,那么 Spring Boot 会创建 MessageCodesResolver (详细信息请查看 DefaultMessageCodesResolver.Format 中的枚举)
 

Static Content

  在默认情况下,Spring Boot 从 classpath 路径下的 /static (或 /publicresources/META-INF/resources )目录 或者 ServletContext 的根目录中提供静态内容,Spring MVC 中使用了 ResourceHttpRequestHandler 便于通过添加自己 WebMvcConfigurer 类并且重写 addResourceHandlers 方法来修改(默认的静态资源处理)逻辑。

  独立的网络应用程序中,容器中默认的 servlet 也被作为后路启用,如果 Spring 不处理它的话,则从 ServletContext 的根目录提供内容。不过大多数时间下不会发生这种情况(除非您修改了缺省的 MVC 配置),因为 Spring 总是通过 DispatcherServlet 来处理 HTTP 请求。

  虽然在默认情况下,资源映射会在 /** 路径上,但是我们可以调换 spring.mvc.static-path-pattern 属性。对于实例,可以实现移动所有资源到 /resources/** 路径,如下所示:

Properties

spring.mvc.static-path-pattern=/resources/**

Yaml

spring:
  mvc:
   static-path-pattern: "/resources/**"

  您可以使用 spring.web.resources.static-locations 属性 (使用目录位置列表用更换默认值) 自定义静态资源路径,而 servlet 根内容路径 “ / ” 自动添加为位置

  除了前面提及的 “ 标准 ” 静态资源位置之外,还有一种特别的情况是 Webjars 的内容。如果它们是以 Webjars 格式打包,那么任何 /webjars/** 路径上的资源都将从 jar 文件中提供。

小贴士

  如果您的应用程序打包成 jar 包,则不使用 src/main/webapp 目录。尽管此目录是一个通俗的标准,但是它仅与 war 包一起工作,并且即使您生成了 jar 包也会通过大多数的构建工具默默无视掉它

  Spring Boot 支持 Spring MVC 提供的先进资源处理功能,允许例如缓存清除的静态资源或使用与版本无关的URL Webjars 文件这类情况。

  要使用与版本无关的 URL Webjars 文件,请添加 webjars-locator-core 依赖,然后声明您的 Webjar 文件。以 jQuery 为例,添加 "/webjars/jquery/jquery.min.js" 文件会导致 "/webjars/jquery/x.y.z/jquery.min.js" 中的 x.y.z 是 Webjar 的版本

注意

  如果您使用 JBoss,需要声明 webjars-locator-jboss-vfs 依赖代替 webjars-locator-core,不然所有的 Webjar 包都会被解析为 404

  要使用缓存清除,以下配置为所有的静态资源配置缓存清除的方案,可以高效地在 URL 中添加内容哈希 ,例如

Properties

spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**

Yaml

spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"

注意

  运行时在模板中链接重写的资源,都要感谢 ResourceUrlEncodingFilter 自动配置的 Thymeleaf 和 FreeMarker 模板引擎。您应当在使用 JSP 时手动声明此过滤器,目前其它模板引擎不自动支持,但是可以自定义模板 宏/助手以及支持 ResourceUrlProvier 的使用

  使用 JavaScript 模块加载器动态加载资源时,重命名文件不是一种选择。这就是为什么也支持其他策略且可以组合的原因。 一个 “ 固定的 ” 策略在 URL 中添加静态版本字符串而不更改文件名,如下所示:

Properties

spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring.web.resources.chain.strategy.fixed.enabled=true
spring.web.resources.chain.strategy.fixed.paths=/js/lib/
spring.web.resources.chain.strategy.fixed.version=v12

Yaml

spring:
  web:
    resources:
      chain:
        strategy:
          content:
            enabled: true
            paths: "/**"
          fixed:
            enabled: true
            paths: "/js/lib/"
            version: "v12"

  有了这个配置,位于 "/js/lib" 下的JavaScript 模块会使用固定的版本策略 ("v12/js/lib/mymodule.js"),而其他资源仍然使用此内容 ()

有关于更多支持选项,请参阅 WebProperties.Resources 获取

小贴士

  此功能已在专门的博客文章和 Spring 框架的参考文档中进行了详细描述

 

Welcome Page

  Spring Boot 支持静态和模板化的欢迎页面,它首先在配置的静态内容位置下寻找 index.html 文件,如果找不到,它就会寻找 index 模板。如果找到任意一个,它就会自动将其作为应用程序的欢迎页面
 

Custom Favicon

  类似于其他的静态资源,Spring Boot 在配置的静态内容位置下查找 favicon.ico 图标文件,如果存在这样的文件,它会自动将其作为应用程序的图标。
 

Path Matching and Content Negotiation

  Spring MVC 通过查看请求路径将传入的 HTTP 请求映射到处理器,并且与应用程序中定义的映射进行匹配(例如,控制器方法上的 @GetMapping 注解)

  Spring Boot 默认禁用后缀模式匹配,意味着像 "GET /projects/spring-boot.json" 的请求将不会匹配 @GetMapping("/projects/spring-boot") 映射。这被认为是 Spring MVC 应用程序的最佳实践。此特性在主要用于过去未正确发送 " Accept " 请求头的 HTTP 客户端;我们需要确保发送正确的内容类型到客户端。如今,内容协商更可靠。

  不过还有其他的方法可以替代后缀匹配,处理始终不能正确接受 “ Accept” 239 请求头的 HTTP 客户端,(例如) 使用查询参数确保像 "GET /projects/spring-boot?format=json" 的请求可以将请求映射到 @GetMapping("/projects/spring-boot")

Properties

spring.mvc.contentnegotiation.favor-parameter=true

Yaml

spring:
  mvc:
    contentnegotiation:
      favor-parameter: true

或者,如果喜欢的话,可以自定义各类的参数名:

Properties

spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam

Yaml

spring:
  mvc:
    contentnegotiation:
      favor-parameter: true
      parameter-name: "myparam"

虽然大多数标准的媒体类型都支持开箱即用,但是也可以定义新的:

Properties

spring.mvc.contentnegotiation.media-types.markdown=text/markdown

Yaml

spring:
  mvc:
    contentnegotiation:
      media-types:
        markdown: "text/markdown"

后缀模式的匹配已经弃用并且在未来的版本中将会被移除,假如您了解警告并且仍然想要让您的应用使用后缀模式进行匹配,那么需要以下配置:

Properties

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-suffix-pattern=true

Yaml

spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-suffix-pattern: true

或者与其打开所有后缀模式,不如仅支持注册后缀模式这样更安全些:

Properties

spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true

Yaml

spring:
  mvc:
    contentnegotiation:
      favor-path-extension: true
    pathmatch:
      use-registered-suffix-pattern: true

 
  作为 Spring Framework 5.3,Spring MVC 支持一些匹配请求路径到控制器处理器的实现策略,原先仅支持 AntPathMatcher 策略,但是现在也提供 PathPatternParser。现在,Spring Boot 提供配置属性选择以及新策略的挑选:

Properties

spring.mvc.pathmatch.matching-strategy=path-pattern-parser

Yaml

spring:
  mvc:
    pathmatch:
      matching-strategy: "path-pattern-parser"

有关于为什么要考虑到这个新的实现,请参考 dedicated blog post

 

注意

  PathPatternParser 是优化的实现但是限制了某些可变路径模式的用法并且不兼容后缀模式的匹配 (spring.mvc.pathmatch.use-suffix-pattern, spring.mvc.pathmatch.use-registeredsuffix-pattern) 或用 servlet 前缀映射的 DispatcherServlet (spring.mvc.servlet.path)。

 

ConfigurableWebBindingInitializer

  Spring MVC 使用 WebBindingInitializer 为特定请求初始化 WebDataBinder ,如果您创建自己的 ConfigurableWebBindingInitializer @Bean, 那么 Spring Boot 会自动配置 Spring MVC 来使用它。
 

Template Engines

  除了 REST 风格的网络服务,您还能使用 Spring MVC 提供动态 HTML 内容,Spring MVC 支持多变的模板技术,其中包括 Thymeleaf、FreeMarker 和 JSP (Java Server Pages:Java服务器页面,是一种动态网页开发技术,其根本是一个简化的 servlet 设计,它是在传统的网络 HTML 文件中插入 Java 程序代码和 JSP 标记,从而形成 JSP 文件,后缀名为 .jsp)。还有就是许多其他的模板引擎包含它们自己的 Spring MVC 集成。
 
Spring Boot 包括对下列模板引擎的自动配置支持 :

  • FreeMarker
  • Groovy
  • Thymeleaf
  • Mustache
     

小贴士

  如果可能的话,应当避免使用 JSP,因为当它们与带有嵌入式的 servlet 容器一起使用时会有一些 已知的限制

当这些模板引擎与默认配置一起使用时,它会从src/main/resources/templates 目录下自动获取

小贴士

  根据运行应用程序的方式不同,IDE 可能会使用不同的 classpath 路径。

  在 IDE 的 main 方法中运行应用程序会导致顺序的不同比如当您从打包的 jar 包中使用 Maven 或 Gradle 运行应用程序时,这可能会导致 Spring Boot 无法找到期望的模板。如果您有这个问题,首先需要在 IDE 中重新整理您的类路径以便正确放置模块的类和资源。

 

Error Handling

  在默认情况下,Spring Boot 提供一个 /error 映射以明智的方式处理所有的错误,并且在 servlet 容器中注册为一个 “ 全局的 ” 错误页面。对于机器客户端,生成一个 JSON 响应包含错误细节,HTTP 状态和异常消息。对于浏览器客户端,有一个 “白色标签的” 错误视图以 HTML 呈现相同的数据(需要定制的话,请添加一个 view 解析为 error 视图)。

  如果您想定制默认的错误处理行为的话,有大量的 server.error 属性能够用于设置,更多细节请查阅附录部分的 “ Server Properties ”

  要更换全部默认的行为,请实现 ErrorController 并且注册该类型的 bean 定义或添加 ErrorAttributes 类型的 bean 以使用现有机制然后更换内容。

小贴士

  自定义 ErrorController 的基类是 BasicErrorController ,如果想要为新的内容类型 (默认专门处理 text/html 并且为所有的其他内容提供回调方法 ) 添加处理器,那就少不了它。为此,需要扩展 BasicErrorController 类,添加一个带有 @RequestMapping 注解和 produces 属性的公开方法,并且创建一个新内容类型的 bean。

 
  您也可以定义一个带有 @ControllerAdvice 注解的类将 JSON 文件自定义为返回特殊的控制器或异常类型,如下所示:

Java

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import
    org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice(basePackageClasses = SomeController.class)
public class MyControllerAdvice extends ResponseEntityExceptionHandler {
    @ResponseBody
    @ExceptionHandler(MyException.class)
    public ResponseEntity<?> handleControllerException(HttpServletRequest request,
                                                       Throwable ex) {
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(new MyErrorBody(status.value(), ex.getMessage()),
                                    status);
    }
    private HttpStatus getStatus(HttpServletRequest request) {
        Integer code = (Integer)
            request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        HttpStatus status = HttpStatus.resolve(code);
        return (status != null) ? status : HttpStatus.INTERNAL_SERVER_ERROR;
    }
}

Kotlin

import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import
org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
import javax.servlet.RequestDispatcher
import javax.servlet.http.HttpServletRequest
@ControllerAdvice(basePackageClasses = [SomeController::class])
class MyControllerAdvice : ResponseEntityExceptionHandler() {
    
    @ResponseBody
    @ExceptionHandler(MyException::class)
    fun handleControllerException(request: HttpServletRequest, ex: Throwable):
    ResponseEntity<*> {
        val status = getStatus(request)
        return ResponseEntity(MyErrorBody(status.value(), ex.message), status)
    }
    private fun getStatus(request: HttpServletRequest): HttpStatus {
        val code = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE) as Int
        val status = HttpStatus.resolve(code)
        return status ?: HttpStatus.INTERNAL_SERVER_ERROR
    }
}

  在上面的示例中,如果在同一包裹中定义的 SomeController 抛出 MyException 异常,会使用 MyErrorBody 的 POJO 的 JSON 形式而不是 ErrorAttributes

  在某些情况下,控制器层级的错误处理不会被 度量设施 记录。此外,应用程序可以通过设置将异常作为请求的属性:

Java

import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
@Controller
public class MyController {
    @ExceptionHandler(CustomException.class)
    String handleCustomException(HttpServletRequest request, CustomException ex) {
        request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex);
        return "errorView";
    }
}

Kotlin

import org.springframework.boot.web.servlet.error.ErrorAttributes
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.ExceptionHandler
import javax.servlet.http.HttpServletRequest
@Controller
class MyController {
    @ExceptionHandler(CustomException::class)
    fun handleCustomException(request: HttpServletRequest, ex: CustomException?):
    String {
        request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex)
        return "errorView"
    }
}

 

Custom Error Pages

  如果您想对于指定的状态码展示自定义的 HTML 错误页面,那么您应当添加文件到 /error 目录下,并且错误页面也可以是 静态 HTML 文件(也就是说,能被添加到任何的静态资源目录下)或通过使用模板生成。此外,文件的名称应当是确切的状态码或序列掩码。

  例如,要映射 404 为静态 HTML 文件,您的目录结构应当如下所示:

src/
 +- main/
 	+- java/
  	| 	+ <source code>
  	+- resources/
      	+- public/
      		+- error/
      		| 	+- 404.html
      		+- <other public assets>

要使用 FreeMarker 模板映射所有的 5xx 错误。您的目录结构应当如下所示:

src/
 +- main/
  	+- java/
  	| 	+ <source code>
  	+- resources/
  		+- templates/
  			+- error/
  			| +- 5xx.ftlh
  			+- <other templates>

对于很多复杂的映射,您也可以添加实现 ErrorViewResolver 接口的 bean,如下所示:

Java

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.ModelAndView;
public class MyErrorViewResolver implements ErrorViewResolver {
   
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
                                         status, Map<String, Object> model) {
        // Use the request or status to optionally return a ModelAndView
        if (status == HttpStatus.INSUFFICIENT_STORAGE) {
            // We could add custom model values here
            new ModelAndView("myview");
        }
        return null;
    }
}

Kotlin

import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver
import org.springframework.http.HttpStatus
import org.springframework.web.servlet.ModelAndView
import javax.servlet.http.HttpServletRequest
class MyErrorViewResolver : ErrorViewResolver {
    override fun resolveErrorView(request: HttpServletRequest, status: HttpStatus,
                                  model: Map<String, Any>): ModelAndView? {
        // Use the request or status to optionally return a ModelAndView
        if (status == HttpStatus.INSUFFICIENT_STORAGE) {
            // We could add custom model values here
            return ModelAndView("myview")
        }
        return null
    }
}

  您也可以使用常规的 Spring MVC 功能例如 @ExceptionHandler 方法 以及@ControllerAdvice 注解,然后,ErrorController 类将会获取任何未处理的异常。
 

Mapping Error Pages outside of Spring MVC

  对于未使用 Spring MVC 的应用程序,您可以直接使用 ErrorPageResiter 接口注册 ErrorPages。此抽象与底层内置的 servlet 容器一起工作即使您没有 Spring MVC DispatchServlet

Java

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
@Configuration(proxyBeanMethods = false)
public class MyErrorPagesConfiguration {
    
    @Bean
    public ErrorPageRegistrar errorPageRegistrar() {
        return this::registerErrorPages;
    }
    
    private void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }
}

Kotlin

import org.springframework.boot.web.server.ErrorPage
import org.springframework.boot.web.server.ErrorPageRegistrar
import org.springframework.boot.web.server.ErrorPageRegistry
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.HttpStatus
@Configuration(proxyBeanMethods = false)
class MyErrorPagesConfiguration {
    
    @Bean
    fun errorPageRegistrar(): ErrorPageRegistrar {
        return ErrorPageRegistrar { registry: ErrorPageRegistry ->
                                   registerErrorPages(registry) }
    }
    
    private fun registerErrorPages(registry: ErrorPageRegistry) {
        registry.addErrorPages(ErrorPage(HttpStatus.BAD_REQUEST, "/400"))
    }
}

 

注意

  如果 错误页面 与最终通过 过滤器 处理的路径一起注册,那么 过滤器 必须明确地注册为 错误 分派器,如下所示:

Java

import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {
    @Bean
    public FilterRegistrationBean<MyFilter> myFilter() {
        FilterRegistrationBean<MyFilter> registration = new
            FilterRegistrationBean<>(new MyFilter());
        // 省略实际业务中的代码逻辑
        registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
        return registration;
    }
}

Kotlin

import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import java.util.EnumSet
import javax.servlet.DispatcherType
@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {
    
    @Bean
    fun myFilter(): FilterRegistrationBean<MyFilter> {
        val registration = FilterRegistrationBean(MyFilter())
        // ...
        registration.setDispatcherTypes(EnumSet.allOf(DispatcherType::class.java))
        return registration
    }
}

注意,默认的 FilterRegisterBean 不包含 错误 分派器类型。
 
Error handling in a war deployment
  当部署到 servlet 容器中时,Spring Boot 使用错误页面过滤器转发带有错误状态的请求到对应的错误页面。这是必要的,因为 servlet 规范确实如此,不提供用于注册错误页面的 API,它只依赖于部署的容器、war 文件和应用程序使用的技术,以及一些也许是必要的额外配置。

  如果响应没有预先提交的话,错误页面过滤器只转发请求到正确的错误页面。在默认情况下,WebSphere 应用程序服务器 8.0 (以及更高版本) 会响应被成功调用 servlet 的服务方法,不过您也可以通过将 com.ibm.ws.webcontainer.invokeFlushAfterService 属性的值设置为 false 来禁用此行为。

  如果您使用的是 Spring Security 并且希望使用它访问错误页面的主体,那么必须配置一个 Spring Security 的过滤器,以便在发生错误时进行调用。为此,请根据需要设置 spring.security.filter.dispatcher-types 属性的值为 asyncerrorforwardrequest
 
CORS Support
  Cross-origin resource sharing(CORS:跨域资源共享)是大部分浏览器实现的 W3C 规范,它允许您以灵活的方式指定授权的跨域资源请求,而不是使用 IFRAME(iframe:HTML 内联框架元素 (