Spring Boot 非常适合 Web 应用程序开发。您可以使用嵌入式 Tomcat、Jetty、Undertow 或 Netty 创建一个自包含的 HTTP 服务器。大多数 Web 应用程序使用该spring-boot-starter-web
模块来快速启动和运行。您还可以选择使用该spring-boot-starter-webflux
模块构建反应式 Web 应用程序。
如果您还没有开发过 Spring Boot Web 应用程序,可以关注“Hello World!” 入门部分中的示例。
1. Servlet Web 应用程序
如果您想构建基于 servlet 的 Web 应用程序,您可以利用 Spring Boot 的 Spring MVC 或 Jersey 自动配置。
1.1“Spring Web MVC 框架”
Spring Web MVC 框架(通常称为“Spring MVC”)是一个丰富的“模型视图控制器”Web 框架。Spring MVC 允许您创建特殊的@Controller
或@RestController
bean 来处理传入的 HTTP 请求。控制器中的方法通过使用@RequestMapping
注解映射到 HTTP。
以下代码显示了一个典型@RestController
的提供 JSON 数据的代码:
功能变体“WebMvc.fn”将路由配置与请求的实际处理分开,如下例所示:
Spring MVC 是核心 Spring Framework 的一部分,详细信息可在参考文档中找到。spring.io/guides上还有一些涵盖 Spring MVC 的指南。
1.1.1Spring MVC 自动配置
Spring Boot 为 Spring MVC 提供了自动配置,适用于大多数应用程序。
自动配置在 Spring 的默认值之上添加了以下特性:
- 包括
ContentNegotiatingViewResolver
和BeanNameViewResolver
豆类。 - 支持提供静态资源,包括对 WebJars 的支持(本文档后面会介绍)。
- 自动注册
Converter
、GenericConverter
和Formatter
bean。 - 支持
HttpMessageConverters
(本文档稍后介绍)。 - 自动注册
MessageCodesResolver
(本文档稍后介绍)。 - 静态
index.html
支持。 -
ConfigurableWebBindingInitializer
bean的自动使用(本文档稍后会介绍)。
如果您想保留那些 Spring Boot MVC 自定义并进行更多MVC 自定义(拦截器、格式化程序、视图控制器和其他功能),您可以添加自己@Configuration
的类型类WebMvcConfigurer
但不 @EnableWebMvc
添加.
如果您想提供、 或的自定义实例RequestMappingHandlerMapping
,并且仍然保留 Spring Boot MVC 自定义,则可以声明一个类型的 bean并使用它来提供这些组件的自定义实例。RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
WebMvcRegistrations
如果你想完全控制 Spring MVC,你可以添加你自己的@Configuration
注释@EnableWebMvc
,或者添加你自己的@Configuration
-annotated DelegatingWebMvcConfiguration
,如@EnableWebMvc
.
1.1.2HttpMessage转换器
Spring MVC 使用该HttpMessageConverter
接口来转换 HTTP 请求和响应。明智的默认设置是开箱即用的。例如,对象可以自动转换为 JSON(通过使用 Jackson 库)或 XML(通过使用 Jackson XML 扩展,如果可用,或者通过使用 JAXB,如果 Jackson XML 扩展不可用)。默认情况下,字符串以UTF-8
.
如果需要添加或自定义转换器,可以使用 Spring Boot 的HttpMessageConverters
类,如下清单所示:
HttpMessageConverter
上下文中存在的任何bean 都将添加到转换器列表中。您也可以以相同的方式覆盖默认转换器。
1.1.3MessageCodesResolver
Spring MVC 有一个生成错误代码的策略,用于从绑定错误中呈现错误消息:MessageCodesResolver
. 如果您设置spring.mvc.message-codes-resolver-format
属性PREFIX_ERROR_CODE
或POSTFIX_ERROR_CODE
,Spring Boot 会为您创建一个(请参阅 中的枚举DefaultMessageCodesResolver.Format)。
1.1.4静态内容
默认情况下,Spring Boot 从类路径中名为/static
(或/public
或/resources
或/META-INF/resources
)的目录或从ServletContext
. 它使用ResourceHttpRequestHandler
来自 Spring MVC 的方法,因此您可以通过添加自己的方法WebMvcConfigurer
并覆盖该addResourceHandlers
方法来修改该行为。
在独立的 Web 应用程序中,容器中的默认 servlet 未启用。可以使用该server.servlet.register-default-servlet
属性启用它。
默认 servlet 充当后备,ServletContext
如果 Spring 决定不处理它,则从根目录提供内容。大多数情况下,这不会发生(除非你修改了默认的 MVC 配置),因为 Spring 总是可以通过DispatcherServlet
.
默认情况下,资源映射在 上/**
,但您可以使用该spring.mvc.static-path-pattern
属性对其进行调整。例如,将所有资源重新定位到/resources/**
可以实现如下:
您还可以使用该spring.web.resources.static-locations
属性自定义静态资源位置(将默认值替换为目录位置列表)。根 servlet 上下文路径"/"
也会自动添加为位置。
除了前面提到的“标准”静态资源位置之外,还为Webjars 内容做了一个特殊情况。/webjars/**
如果以 Webjars 格式打包,则任何具有路径的资源都将从 jar 文件中提供。
Spring Boot 还支持 Spring MVC 提供的高级资源处理功能,允许使用诸如缓存清除静态资源或为 Webjar 使用与版本无关的 URL 等用例。
要为 Webjar 使用与版本无关的 URL,请添加webjars-locator-core
依赖项。然后声明你的 Webjar。以jQuery为例,添加"/webjars/jquery/jquery.min.js"
结果在"/webjars/jquery/x.y.z/jquery.min.js"
哪里x.y.z
是Webjar版本。
要使用缓存清除,以下配置为所有静态资源配置缓存清除解决方案,有效地在 URL 中添加内容哈希,例如<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
:
特性
例如,当使用 JavaScript 模块加载器动态加载资源时,重命名文件不是一种选择。这就是为什么还支持其他策略并且可以组合的原因。“固定”策略在 URL 中添加静态版本字符串而不更改文件名,如下例所示:
特性
使用此配置,位于下的 JavaScript 模块"/js/lib/"
使用固定版本控制策略 ( "/v12/js/lib/mymodule.js"
),而其他资源仍使用内容策略 ( <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
)。
有关WebProperties.Resources更多支持的选项,请参阅。
1.1.5欢迎页面
Spring Boot 支持静态和模板化的欢迎页面。index.html
它首先在配置的静态内容位置中查找文件。如果没有找到,它会寻找一个index
模板。如果找到其中任何一个,它会自动用作应用程序的欢迎页面。
1.1.6自定义网站图标
与其他静态资源一样,Spring Bootfavicon.ico
在配置的静态内容位置中检查 a。如果存在这样的文件,它会自动用作应用程序的图标。
1.1.7路径匹配和内容协商
Spring MVC 可以通过查看请求路径并将其与应用程序中定义的映射匹配(例如,@GetMapping
控制器方法上的注释)将传入的 HTTP 请求映射到处理程序。
Spring Boot 默认选择禁用后缀模式匹配,这意味着 like 的请求"GET /projects/spring-boot.json"
不会匹配到@GetMapping("/projects/spring-boot")
映射。这被认为是Spring MVC 应用程序的最佳实践。过去,此功能主要对未发送正确“Accept”请求标头的 HTTP 客户端有用;我们需要确保向客户端发送正确的内容类型。如今,内容协商更加可靠。
还有其他方法可以处理不能始终发送正确的“接受”请求标头的 HTTP 客户端。我们可以不使用后缀匹配,而是使用查询参数来确保请求 like"GET /projects/spring-boot?format=json"
将被映射到@GetMapping("/projects/spring-boot")
:
特性
或者,如果您更喜欢使用不同的参数名称:
特性
大多数标准媒体类型都支持开箱即用,但您也可以定义新的媒体类型:
特性
后缀模式匹配已弃用,并将在未来版本中删除。如果您了解这些警告并且仍然希望您的应用程序使用后缀模式匹配,则需要以下配置:
特性
或者,与其打开所有后缀模式,不如只支持已注册的后缀模式更安全:
特性
从 Spring Framework 5.3 开始,Spring MVC 支持多种实现策略,用于将请求路径匹配到 Controller 处理程序。它以前只支持该AntPathMatcher
策略,但现在它也提供PathPatternParser
. Spring Boot 现在提供了一个配置属性来选择和选择新策略:
特性
有关为什么应该考虑这个新实现的更多详细信息,请参阅 专门的博客文章。
1.1.8ConfigurableWebBindingInitializer
Spring MVC 使用 a来为特定请求WebBindingInitializer
初始化 a 。WebDataBinder
如果你自己创建ConfigurableWebBindingInitializer
@Bean
,Spring Boot 会自动配置 Spring MVC 来使用它。
1.1.9模板引擎
除了 REST Web 服务,您还可以使用 Spring MVC 来提供动态 HTML 内容。Spring MVC 支持多种模板技术,包括 Thymeleaf、FreeMarker 和 JSP。此外,许多其他模板引擎包括他们自己的 Spring MVC 集成。
Spring Boot 包括对以下模板引擎的自动配置支持:
- *标记
- 时髦的
- 百里香叶
- 胡子
当您将这些模板引擎之一与默认配置一起使用时,您的模板会自动从src/main/resources/templates
.
1.1.10错误处理
默认情况下,Spring Boot 提供了一个/error
以合理方式处理所有错误的映射,并将其注册为 servlet 容器中的“全局”错误页面。对于机器客户端,它会生成一个 JSON 响应,其中包含错误、HTTP 状态和异常消息的详细信息。对于浏览器客户端,有一个“whitelabel”错误视图,它以 HTML 格式呈现相同的数据(要自定义它,添加一个View
解析为 的error
)。
server.error
如果要自定义默认错误处理行为,可以设置许多属性。请参阅附录的“服务器属性”部分。
要完全替换默认行为,您可以实现ErrorController
并注册该类型的 bean 定义或添加类型的 beanErrorAttributes
以使用现有机制但替换内容。
您还可以定义一个带有注释的类@ControllerAdvice
来自定义 JSON 文档以返回特定控制器和/或异常类型,如以下示例所示:
爪哇
科特林
在前面的示例中,如果MyException
由与 相同的包中定义的控制器抛出,则使用 POJOSomeController
的 JSON 表示MyErrorBody
而不是ErrorAttributes
表示。
在某些情况下,在控制器级别处理的错误不会被度量基础设施记录。应用程序可以通过将处理的异常设置为请求属性来确保将此类异常与请求指标一起记录:
自定义错误页面
如果要显示给定状态代码的自定义 HTML 错误页面,可以将文件添加到/error
目录。错误页面可以是静态 HTML(即添加到任何静态资源目录下),也可以使用模板构建。文件名应该是准确的状态码或序列掩码。
例如,要映射404
到静态 HTML 文件,您的目录结构如下:
要使用 FreeMarker 模板映射所有5xx
错误,您的目录结构如下:
对于更复杂的映射,您还可以添加实现ErrorViewResolver
接口的 bean,如下例所示:
您还可以使用常规 Spring MVC 功能,例如@ExceptionHandler方法和@ControllerAdvice. 然后ErrorController
拾取任何未处理的异常。
在 Spring MVC 之外映射错误页面
对于不使用 Spring MVC 的应用,可以使用ErrorPageRegistrar
接口直接注册ErrorPages
。这种抽象直接与底层的嵌入式 servlet 容器一起工作,即使您没有 Spring MVC 也可以工作DispatcherServlet
。
爪哇
科特林
请注意,默认值FilterRegistrationBean
不包括ERROR
调度程序类型。
WAR 部署中的错误处理
当部署到 servlet 容器时,Spring Boot 使用其错误页面过滤器将具有错误状态的请求转发到相应的错误页面。这是必要的,因为 servlet 规范不提供用于注册错误页面的 API。根据您将 war 文件部署到的容器以及您的应用程序使用的技术,可能需要一些额外的配置。
如果响应尚未提交,错误页面过滤器只能将请求转发到正确的错误页面。默认情况下,WebSphere Application Server 8.0 和更高版本在成功完成 servlet 的服务方法时提交响应。com.ibm.ws.webcontainer.invokeFlushAfterService
您应该通过设置来禁用此行为false
。
如果您使用 Spring Security 并希望在错误页面中访问主体,则必须配置 Spring Security 的过滤器以在错误调度时调用。为此,请将spring.security.filter.dispatcher-types
属性设置为async, error, forward, request
。
1.1.11CORS 支持
跨域资源共享(CORS) 是大多数浏览器实现的W3C 规范,它允许您以灵活的方式指定授权哪种跨域请求,而不是使用 IFRAME 或 JSONP 等一些不太安全和不太强大的方法。
从 4.2 版开始,Spring MVC支持 CORS。在 Spring Boot 应用程序中使用带有注释的控制器方法 CORS 配置@CrossOrigin不需要任何特定配置。 可以通过使用自定义方法注册 bean来定义全局 CORS 配置,如下例所示:WebMvcConfigurer
addCorsMappings(CorsRegistry)
1.2. JAX-RS 和泽西岛
如果您更喜欢 REST 端点的 JAX-RS 编程模型,则可以使用其中一种可用的实现来代替 Spring MVC。 Jersey和Apache CXF开箱即用,效果很好。CXF 要求您在应用程序上下文中将其Servlet
或注册Filter
为 a 。@Bean
Jersey 有一些原生的 Spring 支持,所以我们还在 Spring Boot 中为它提供了自动配置支持,以及一个 starter。
要开始使用 Jersey,请包含spring-boot-starter-jersey
作为依赖项,然后您需要一种@Bean
类型ResourceConfig
,您可以在其中注册所有端点,如以下示例所示:
对于更高级的自定义,您还可以注册任意数量的实现ResourceConfigCustomizer
.
所有注册的端点都应该@Components
带有 HTTP 资源注释(@GET
和其他),如以下示例所示:
由于Endpoint
是 Spring @Component
,其生命周期由 Spring 管理,您可以使用@Autowired
注解注入依赖项并使用@Value
注解注入外部配置。默认情况下,Jersey servlet 已注册并映射到/*
. 您可以通过添加@ApplicationPath
到您的ResourceConfig
.
默认情况下,Jersey 设置为名为@Bean
的类型的 servlet 。默认情况下,servlet 是延迟初始化的,但您可以通过设置来自定义该行为。您可以通过创建自己的同名 bean 来禁用或覆盖该 bean。您还可以通过设置使用过滤器而不是 servlet (在这种情况下,要替换或覆盖的是)。过滤器有一个,您可以使用 进行设置。当使用 Jersey 作为过滤器时,必须存在一个处理任何未被 Jersey 拦截的请求的 servlet。如果您的应用程序不包含这样的 servlet,您可能希望通过设置来启用默认 servletServletRegistrationBean
jerseyServletRegistration
spring.jersey.servlet.load-on-startup
spring.jersey.type=filter
@Bean
jerseyFilterRegistration
@Order
spring.jersey.filter.order
server.servlet.register-default-servlet
true
. servlet 和过滤器注册都可以通过使用spring.jersey.init.*
指定属性映射来指定初始化参数。
1.3. 嵌入式 Servlet 容器支持
对于 servlet 应用程序,Spring Boot 包括对嵌入式Tomcat、Jetty和Undertow服务器的支持。大多数开发人员使用适当的“Starter”来获取完全配置的实例。默认情况下,嵌入式服务器在 port 上侦听 HTTP 请求8080
。
1.3.1Servlet、过滤器和侦听器
使用嵌入式 servlet 容器时,您可以通过使用 Spring beans 或扫描 servlet 组件来注册 servlet、过滤器和 servlet 规范中的所有侦听器(例如HttpSessionListener
)。
将 Servlet、过滤器和侦听器注册为 Spring Bean
任何作为 Spring bean 的Servlet
、Filter
或 servlet*Listener
实例都会在嵌入式容器中注册。如果您想application.properties
在配置期间引用一个值,这会特别方便。
默认情况下,如果上下文只包含一个 Servlet,它会映射到/
. 在多个 servlet bean 的情况下,bean 名称用作路径前缀。过滤器映射到/*
.
如果基于约定的映射不够灵活,您可以使用ServletRegistrationBean
、FilterRegistrationBean
和ServletListenerRegistrationBean
类进行完全控制。
让过滤器豆无序通常是安全的。如果需要特定的顺序,您应该使用注释Filter
或@Order
使其实现Ordered
。您不能通过使用Filter
注释其 bean 方法来配置 a 的顺序@Order
。如果您无法更改Filter
要添加@Order
或实现的类Ordered
,则必须FilterRegistrationBean
为定义一个并使用该方法Filter
设置注册 bean 的顺序。setOrder(int)
避免在 处配置读取请求正文的过滤器Ordered.HIGHEST_PRECEDENCE
,因为它可能会违反应用程序的字符编码配置。如果 servlet 过滤器包装了请求,则应使用小于或等于 的顺序对其进行配置OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER
。
1.3.2. Servlet 上下文初始化
嵌入式 servlet 容器不直接执行 servlet 3.0+javax.servlet.ServletContainerInitializer
接口或 Spring 的org.springframework.web.WebApplicationInitializer
接口。这是一个有意的设计决策,旨在降低设计为在战争中运行的第三方库可能会破坏 Spring Boot 应用程序的风险。
如果您需要在 Spring Boot 应用程序中执行 servlet 上下文初始化,您应该注册一个实现该org.springframework.boot.web.servlet.ServletContextInitializer
接口的 bean。单一onStartup
方法提供对 的访问,ServletContext
并且如有必要,可以轻松地用作现有WebApplicationInitializer
.
扫描 Servlet、过滤器和侦听器
使用嵌入式容器时,使用 、 和 注释的类的自动@WebServlet
注册@WebFilter
可以@WebListener
使用@ServletComponentScan
.
1.3.3. ServletWebServerApplicationContext
在底层,Spring Boot 使用不同类型的ApplicationContext
嵌入式 servlet 容器支持。这是一种通过搜索单个bean来引导自身ServletWebServerApplicationContext
的特殊类型。通常 a 、或已自动配置。WebApplicationContext
ServletWebServerFactory
TomcatServletWebServerFactory
JettyServletWebServerFactory
UndertowServletWebServerFactory
在嵌入式容器设置中,ServletContext
设置为在应用程序上下文初始化期间发生的服务器启动的一部分。因为这个 beanApplicationContext
不能用ServletContext
. 解决此问题的一种方法是将注入ApplicationContext
作为 bean 的依赖项并ServletContext
仅在需要时访问。另一种方法是在服务器启动后使用回调。这可以使用ApplicationListener
如下来完成ApplicationStartedEvent
:
1.3.4定制嵌入式 Servlet 容器
可以使用 SpringEnvironment
属性配置常见的 servlet 容器设置。通常,您会在application.properties
orapplication.yaml
文件中定义属性。
常见的服务器设置包括:
- 网络设置:监听传入 HTTP 请求的端口 (
server.port
)、要绑定的接口地址server.address
等。 - 会话设置:会话是否持久(
server.servlet.session.persistent
)、会话超时(server.servlet.session.timeout
)、会话数据的位置(server.servlet.session.store-dir
)和会话cookie配置(server.servlet.session.cookie.*
)。 - 错误管理:错误页面的位置(
server.error.path
)等。 - SSL
- HTTP 压缩
Spring Boot 尽可能地尝试公开常用设置,但这并不总是可能的。对于这些情况,专用命名空间提供特定于服务器的定制(请参阅server.tomcat
和server.undertow
)。例如,可以使用嵌入式 servlet 容器的特定功能配置访问日志。
SameSite Cookie
Web 浏览器可以使用SameSite
cookie 属性来控制是否以及如何在跨站点请求中提交 cookie。该属性与现代 Web 浏览器特别相关,这些浏览器已开始更改缺少该属性时使用的默认值。
如果要更改SameSite
会话 cookie 的属性,可以使用该server.servlet.session.cookie.same-site
属性。自动配置的 Tomcat、Jetty 和 Undertow 服务器支持此属性。它还用于配置基于 Spring Session servlet 的SessionRepository
bean。
例如,如果您希望会话 cookie 具有SameSite
属性None
,您可以将以下内容添加到您的application.properties
orapplication.yaml
文件中:
特性
如果您想更改SameSite
添加到您的其他 cookie 上的属性HttpServletResponse
,您可以使用CookieSameSiteSupplier
. CookieSameSiteSupplier
传递了一个并且Cookie
可能返回一个SameSite
值,或者null
。
您可以使用许多便利工厂和过滤方法来快速匹配特定的 cookie。例如,添加以下 bean 将自动为所有名称与正则表达式匹配的 cookie应用SameSite
of 。Lax
myapp.*
程序化定制
如果您需要以编程方式配置您的嵌入式 servlet 容器,您可以注册一个实现该WebServerFactoryCustomizer
接口的 Spring bean。 WebServerFactoryCustomizer
提供对 的访问ConfigurableServletWebServerFactory
,其中包括许多自定义设置方法。以下示例显示了以编程方式设置端口:
TomcatServletWebServerFactory
,JettyServletWebServerFactory
并且UndertowServletWebServerFactory
是它们的专用变体,ConfigurableServletWebServerFactory
分别为 Tomcat、Jetty 和 Undertow 提供了额外的自定义设置方法。以下示例显示了如何自定义TomcatServletWebServerFactory
提供对特定于 Tomcat 的配置选项的访问:
直接自定义 ConfigurableServletWebServerFactory
对于需要从 扩展的更高级的用例ServletWebServerFactory
,您可以自己公开这种类型的 bean。
为许多配置选项提供了设置器。如果您需要做一些更奇特的事情,还提供了几个受保护的方法“钩子”。有关详细信息,请参阅源代码文档。
1.3.5。JSP 限制
在运行使用嵌入式 servlet 容器(并打包为可执行存档)的 Spring Boot 应用程序时,JSP 支持存在一些限制。
- 使用 Jetty 和 Tomcat,如果您使用战争包装,它应该可以工作。一个可执行的战争将在使用 启动时工作
java -jar
,并且也可以部署到任何标准容器。使用可执行 jar 时不支持 JSP。 - Undertow 不支持 JSP。
- 创建自定义
error.jsp
页面不会覆盖错误处理的默认视图。 应改为使用自定义错误页面。
2. 反应式 Web 应用程序
Spring Boot 通过为 Spring Webflux 提供自动配置来简化响应式 Web 应用程序的开发。
2.1“Spring WebFlux 框架”
Spring WebFlux 是 Spring Framework 5.0 中引入的新的响应式 Web 框架。与 Spring MVC 不同,它不需要 servlet API,完全异步和非阻塞,并通过Reactor 项目实现Reactive Streams规范。
Spring WebFlux 有两种风格:函数式和基于注释的。基于注解的模型非常接近 Spring MVC 模型,如下例所示:
功能变体“WebFlux.fn”将路由配置与请求的实际处理分开,如下例所示:
WebFlux 是 Spring Framework 的一部分,详细信息可在其参考文档中找到。
首先,将spring-boot-starter-webflux
模块添加到您的应用程序中。
2.1.1Spring WebFlux 自动配置
Spring Boot 为 Spring WebFlux 提供了自动配置,适用于大多数应用程序。
自动配置在 Spring 的默认值之上添加了以下特性:
-
HttpMessageReader
为和HttpMessageWriter
实例配置编解码器(本文档稍后将介绍)。 - 支持提供静态资源,包括对 WebJars 的支持(本文档稍后会介绍)。
如果你想保留 Spring Boot WebFlux 的特性并且你想添加额外的 WebFlux 配置,你可以添加你自己@Configuration
的类型WebFluxConfigurer
但没有 @EnableWebFlux
.
如果你想完全控制 Spring WebFlux,你可以添加自己的@Configuration
带有@EnableWebFlux
.
2.1.2. 带有 HttpMessageReaders 和 HttpMessageWriters 的 HTTP 编解码器
Spring WebFlux 使用HttpMessageReader
和HttpMessageWriter
接口来转换 HTTP 请求和响应。CodecConfigurer
通过查看类路径中可用的库,它们被配置为具有合理的默认值。
Spring Boot 为编解码器提供了专用的配置属性,spring.codec.*
. 它还通过使用CodecCustomizer
实例来应用进一步的定制。例如,spring.jackson.*
配置密钥应用于 Jackson 编解码器。
如果需要添加或自定义编解码器,可以创建自定义CodecCustomizer
组件,如下例所示:
您还可以利用Boot 的自定义 JSON 序列化器和反序列化器。
2.1.3静态内容
默认情况下,Spring Boot 从类路径中名为/static
(or /public
or /resources
or /META-INF/resources
) 的目录中提供静态内容。它使用ResourceWebHandler
来自 Spring WebFlux 的方法,因此您可以通过添加自己的方法WebFluxConfigurer
并覆盖该addResourceHandlers
方法来修改该行为。
默认情况下,资源映射在 上/**
,但您可以通过设置spring.webflux.static-path-pattern
属性来调整它。例如,将所有资源重新定位到/resources/**
可以实现如下:
特性
您还可以使用自定义静态资源位置spring.web.resources.static-locations
。这样做会将默认值替换为目录位置列表。如果您这样做,默认的欢迎页面检测将切换到您的自定义位置。因此,如果index.html
启动时在您的任何位置有一个,它就是应用程序的主页。
除了前面列出的“标准”静态资源位置之外,还为Webjars 内容做了一个特殊情况。/webjars/**
如果以 Webjars 格式打包,则任何具有路径的资源都将从 jar 文件中提供。
2.1.4欢迎页面
Spring Boot 支持静态和模板化的欢迎页面。index.html
它首先在配置的静态内容位置中查找文件。如果没有找到,它会寻找一个index
模板。如果找到其中任何一个,它会自动用作应用程序的欢迎页面。
2.1.5模板引擎
除了 REST Web 服务,您还可以使用 Spring WebFlux 来提供动态 HTML 内容。Spring WebFlux 支持多种模板技术,包括 Thymeleaf、FreeMarker 和 Mustache。
Spring Boot 包括对以下模板引擎的自动配置支持:
- *标记
- 百里香叶
- 胡子
当您将这些模板引擎之一与默认配置一起使用时,您的模板会自动从src/main/resources/templates
.
2.1.6错误处理
Spring Boot 提供了一种WebExceptionHandler
以合理的方式处理所有错误的方法。它在处理顺序中的位置紧接在 WebFlux 提供的处理程序之前,这些处理程序被认为是最后一个。对于机器客户端,它会生成一个 JSON 响应,其中包含错误、HTTP 状态和异常消息的详细信息。对于浏览器客户端,有一个“whitelabel”错误处理程序以 HTML 格式呈现相同的数据。您还可以提供自己的 HTML 模板来显示错误(请参阅下一节)。
自定义此功能的第一步通常涉及使用现有机制但替换或增加错误内容。为此,您可以添加一个 bean 类型ErrorAttributes
。
要更改错误处理行为,您可以实现ErrorWebExceptionHandler
并注册该类型的 bean 定义。由于 anErrorWebExceptionHandler
是相当底层的,Spring Boot 还提供了一种方便AbstractErrorWebExceptionHandler
的方式让您以 WebFlux 函数式的方式处理错误,如下例所示:
为了更完整的画面,也可以DefaultErrorWebExceptionHandler
直接子类化,重写具体的方法。
在某些情况下,在控制器或处理程序功能级别处理的错误不会被度量基础设施记录。应用程序可以通过将处理的异常设置为请求属性来确保将此类异常与请求指标一起记录:
自定义错误页面
如果要显示给定状态代码的自定义 HTML 错误页面,可以将文件添加到/error
目录。错误页面可以是静态 HTML(即添加到任何静态资源目录下)或使用模板构建。文件名应该是准确的状态码或序列掩码。
例如,要映射404
到静态 HTML 文件,您的目录结构如下:
要使用 Mustache 模板映射所有5xx
错误,您的目录结构如下:
2.1.7网页过滤器
Spring WebFlux 提供了一个WebFilter
接口,可以实现过滤 HTTP 请求-响应交换。 WebFilter
在应用程序上下文中找到的 bean 将自动用于过滤每个交换。
如果过滤器的顺序很重要,它们可以实现Ordered
或用@Order
. Spring Boot 自动配置可能会为您配置 Web 过滤器。这样做时,将使用下表中显示的订单:
网页过滤器 |
命令 |
|
|
|
|
|
|
2.2. 嵌入式反应式服务器支持
Spring Boot 包括对以下嵌入式响应式 Web 服务器的支持:Reactor Netty、Tomcat、Jetty 和 Undertow。大多数开发人员使用适当的“Starter”来获取完全配置的实例。默认情况下,嵌入式服务器在端口 8080 上侦听 HTTP 请求。
2.3. 反应式服务器资源配置
当自动配置 Reactor Netty 或 Jetty 服务器时,Spring Boot 将创建特定的 bean,这些 bean 将为服务器实例提供 HTTP 资源:ReactorResourceFactory
或JettyResourceFactory
.
默认情况下,这些资源也将与 Reactor Netty 和 Jetty 客户端共享以获得最佳性能,给定:
- 服务器和客户端使用相同的技术
- 客户端实例是使用
WebClient.Builder
Spring Boot 自动配置的 bean构建的
开发人员可以通过提供自定义ReactorResourceFactory
或JettyResourceFactory
bean 来覆盖 Jetty 和 Reactor Netty 的资源配置——这将应用于客户端和服务器。
您可以在WebClient 运行时部分了解有关客户端资源配置的更多信息。
3. 优雅关机
所有四个嵌入式 Web 服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)以及反应式和基于 servlet 的 Web 应用程序都支持优雅关闭。它作为关闭应用程序上下文的一部分发生,并在停止SmartLifecycle
bean 的最早阶段执行。此停止处理使用超时提供宽限期,在此期间将允许完成现有请求,但不允许新请求。不允许新请求的确切方式因所使用的 Web 服务器而异。Jetty、Reactor Netty 和 Tomcat 将停止接受网络层的请求。Undertow 将接受请求,但会立即以服务不可用 (503) 响应进行响应。
要启用正常关机,请配置该server.shutdown
属性,如以下示例所示:
特性
要配置超时时间,请配置spring.lifecycle.timeout-per-shutdown-phase
属性,如以下示例所示:
特性
4. Spring 安全
如果Spring Security在类路径上,则默认情况下 Web 应用程序是安全的。Spring Boot 依赖 Spring Security 的内容协商策略来确定是否httpBasic
使用formLogin
. 要为 Web 应用程序添加方法级别的安全性,您还可以添加@EnableGlobalMethodSecurity
所需的设置。更多信息可以在Spring Security Reference Guide中找到。
默认UserDetailsService
只有一个用户。用户名为user
,密码是随机的,在应用启动时打印在 WARN 级别,如下例所示:
您可以通过提供spring.security.user.name
和来更改用户名和密码spring.security.user.password
。
默认情况下,您在 Web 应用程序中获得的基本功能是:
- 一个
UserDetailsService
(或ReactiveUserDetailsService
在 WebFlux 应用程序的情况下)具有内存存储的 bean 和具有生成密码的单个用户(请参阅SecurityProperties.User用户属性)。 -
Accept
整个应用程序(包括执行器端点,如果执行器位于类路径上)的基于表单的登录或 HTTP 基本安全性(取决于请求中的标头)。 - A
DefaultAuthenticationEventPublisher
用于发布身份验证事件。
AuthenticationEventPublisher
您可以通过为其添加 bean 来提供不同的。
4.1。MVC 安全
默认安全配置在SecurityAutoConfiguration
和中实现UserDetailsServiceAutoConfiguration
。 为 Web 安全SecurityAutoConfiguration
导入并配置身份验证,这在非 Web 应用程序中也相关。要完全关闭默认的 Web 应用程序安全配置或组合多个 Spring Security 组件,例如 OAuth2 客户端和资源服务器,请添加一个类型的 bean (这样做不会禁用配置或执行器的安全性)。SpringBootWebSecurityConfiguration
UserDetailsServiceAutoConfiguration
SecurityFilterChain
UserDetailsService
要关闭配置,您可以添加类型为 、或UserDetailsService
的 bean 。UserDetailsService
AuthenticationProvider
AuthenticationManager
可以通过添加自定义SecurityFilterChain
或WebSecurityConfigurerAdapter
bean 来覆盖访问规则。Spring Boot 提供了方便的方法,可用于覆盖执行器端点和静态资源的访问规则。 EndpointRequest
可用于创建RequestMatcher
基于management.endpoints.web.base-path
属性的。 PathRequest
可用于RequestMatcher
在常用位置创建资源。
4.2. WebFlux 安全
与 Spring MVC 应用程序类似,您可以通过添加spring-boot-starter-security
依赖项来保护您的 WebFlux 应用程序。默认安全配置在ReactiveSecurityAutoConfiguration
和中实现UserDetailsServiceAutoConfiguration
。 为 Web 安全ReactiveSecurityAutoConfiguration
导入并配置身份验证,这在非 Web 应用程序中也相关。要完全关闭默认的 Web 应用程序安全配置,您可以添加一个类型的 bean (这样做不会禁用配置或执行器的安全性)。WebFluxSecurityConfiguration
UserDetailsServiceAutoConfiguration
WebFilterChainProxy
UserDetailsService
要关闭配置,您可以添加类型为或UserDetailsService
的 bean 。ReactiveUserDetailsService
ReactiveAuthenticationManager
SecurityWebFilterChain
可以通过添加自定义bean来配置访问规则和多个 Spring Security 组件(例如 OAuth 2 客户端和资源服务器)的使用。Spring Boot 提供了方便的方法,可用于覆盖执行器端点和静态资源的访问规则。 EndpointRequest
可用于创建ServerWebExchangeMatcher
基于management.endpoints.web.base-path
属性的。
PathRequest
可用于ServerWebExchangeMatcher
在常用位置创建资源。
例如,您可以通过添加以下内容来自定义您的安全配置:
4.3. OAuth2
OAuth2是 Spring 支持的广泛使用的授权框架。
4.3.1客户
如果您有spring-security-oauth2-client
类路径,则可以利用一些自动配置来设置 OAuth2/Open ID Connect 客户端。此配置使用OAuth2ClientProperties
. 相同的属性适用于 servlet 和响应式应用程序。
您可以在前缀下注册多个 OAuth2 客户端和提供程序spring.security.oauth2.client
,如下例所示:
特性
对于支持OpenID Connect 发现的 OpenID Connect 提供者,可以进一步简化配置。提供者需要配置一个issuer-uri
URI,它声明为它的颁发者标识符。例如,如果issuer-uri
提供的是“https://example.com”,那么OpenID Provider Configuration Request
将对“https://example.com/.well-known/openid-configuration”进行设置。结果预计为OpenID Provider Configuration Response
. 以下示例显示了如何使用以下内容配置 OpenID Connect 提供程序issuer-uri
:
默认情况下,Spring SecurityOAuth2LoginAuthenticationFilter
只处理匹配的 URL /login/oauth2/code/*
。如果要自定义redirect-uri
以使用不同的模式,则需要提供配置来处理该自定义模式。例如,对于 servlet 应用程序,您可以添加自己的SecurityFilterChain
类似于以下内容:
通用提供者的 OAuth2 客户端注册
对于常见的 OAuth2 和 OpenID 提供程序,包括 Google、Github、Facebook 和 Okta,我们提供了一组提供程序默认值(分别为google
、github
、facebook
和okta
)。
如果您不需要自定义这些提供程序,您可以将provider
属性设置为您需要为其推断默认值的那个。此外,如果客户端注册的密钥与默认支持的提供程序匹配,Spring Boot 也会推断出这一点。
换句话说,以下示例中的两个配置使用了 Google 提供程序:
特性
4.3.2. 资源服务器
如果你spring-security-oauth2-resource-server
的类路径上有,Spring Boot 可以设置一个 OAuth2 资源服务器。对于 JWT 配置,需要指定 JWK Set URI 或 OIDC Issuer URI,如以下示例所示:
特性
特性
相同的属性适用于 servlet 和响应式应用程序。
或者,您可以为 servlet 应用程序或响应式应用程序定义自己的JwtDecoder
bean 。ReactiveJwtDecoder
在使用不透明令牌而不是 JWT 的情况下,您可以配置以下属性以通过自省来验证令牌:
特性
同样,相同的属性适用于 servlet 和响应式应用程序。
或者,您可以为 servlet 应用程序或响应式应用程序定义自己的OpaqueTokenIntrospector
bean 。ReactiveOpaqueTokenIntrospector
4.3.3. 授权服务器
目前,Spring Security 不支持实现 OAuth 2.0 授权服务器。但是,此功能可从Spring Security OAuth项目中获得,该项目最终将被 Spring Security 完全取代。在此之前,您可以使用该spring-security-oauth2-autoconfigure
模块轻松设置 OAuth 2.0 授权服务器;有关说明,请参阅其文档。
4.4. SAML 2.0
4.4.1信赖方
如果您spring-security-saml2-service-provider
的类路径中有,您可以利用一些自动配置来设置 SAML 2.0 依赖方。此配置使用Saml2RelyingPartyProperties
.
依赖方注册代表身份提供者 IDP 和服务提供者 SP 之间的配对配置。您可以在前缀下注册多个信赖方spring.security.saml2.relyingparty
,如下例所示:
特性
对于 SAML2 注销,默认情况下,Spring SecuritySaml2LogoutRequestFilter
只Saml2LogoutResponseFilter
处理匹配的 URL /logout/saml2/slo
。如果您想自定义url
AP 发起的注销请求发送到的对象或response-url
AP 发送注销响应的对象,以使用不同的模式,您需要提供配置来处理该自定义模式。例如,对于 servlet 应用程序,您可以添加自己的SecurityFilterChain
类似于以下内容:
5.春季会议
Spring Boot 为各种数据存储提供Spring Session自动配置。在构建 servlet Web 应用程序时,可以自动配置以下存储:
- JDBC
- 雷迪斯
- 榛树
- MongoDB
此外, Apache Geode 的Spring Boot提供了将 Apache Geode 用作会话存储的自动配置。
servlet 自动配置取代了使用@Enable*HttpSession
.
在构建响应式 Web 应用程序时,可以自动配置以下存储:
- 雷迪斯
- MongoDB
反应式自动配置取代了使用@Enable*WebSession
.
如果类路径中存在单个 Spring Session 模块,则 Spring Boot 会自动使用该存储实现。如果您有多个实现,则必须选择StoreType您希望用来存储会话的那个。例如,要将 JDBC 用作后端存储,您可以按如下方式配置您的应用程序:
特性
每个商店都有特定的附加设置。例如,可以为 JDBC 存储自定义表的名称,如下例所示:
特性
要设置会话的超时,您可以使用该spring.session.timeout
属性。如果该属性未使用 servlet Web 应用程序设置,则自动配置回退到server.servlet.session.timeout
.
@Enable*HttpSession
您可以使用(servlet) 或@Enable*WebSession
(reactive)控制 Spring Session 的配置。这将导致自动配置退出。然后可以使用注解的属性而不是前面描述的配置属性来配置 Spring Session。
6. Spring for GraphQL
如果您想构建 GraphQL 应用程序,您可以利用 Spring Boot 的Spring for GraphQL自动配置。Spring for GraphQL 项目基于GraphQL Java。您spring-boot-starter-graphql
至少需要启动器。由于 GraphQL 与传输无关,因此您还需要在应用程序中添加一个或多个启动器,以便在 Web 上公开您的 GraphQL API:
起动机 |
运输 |
执行 |
|
HTTP |
春季MVC |
|
网络套接字 |
Servlet 应用程序的 WebSocket |
|
HTTP、WebSocket |
Spring WebFlux |
|
TCP、网络套接字 |
Reactor Netty 上的 Spring WebFlux |
6.1GraphQL 架构
Spring GraphQL 应用程序需要在启动时定义模式。默认情况下,您可以在下编写“.graphqls”或“.gqls”模式文件src/main/resources/graphql/**
,Spring Boot 会自动拾取它们。您可以使用 自定义位置spring.graphql.schema.locations
和使用spring.graphql.schema.file-extensions
.
在以下部分中,我们将考虑这个示例 GraphQL 模式,它定义了两种类型和两个查询:
6.2. GraphQL 运行时接线
GraphQL JavaRuntimeWiring.Builder
可用于DataFetcher`s, and more. You can declare `RuntimeWiringConfigurer
在 Spring 配置中注册自定义标量类型、指令、类型解析器、bean,以访问RuntimeWiring.Builder
. Spring Boot 检测到此类 bean 并将它们添加到GraphQlSource builder中。
然而,通常情况下,应用程序不会DataFetcher
直接实现,而是创建带注释的控制器。Spring Boot 将自动检测@Controller
带有注释处理程序方法的类并将它们注册为DataFetcher`s. Here’s a sample implementation for our greeting query with a `@Controller
类:
6.3. Querydsl 和 QueryByExample 存储库支持
Spring Data 提供对 Querydsl 和 QueryByExample 存储库的支持。Spring GraphQL 可以将 Querydsl 和 QueryByExample 存储库配置为DataFetcher.
Spring Data 存储库使用@GraphQlRepository
以下之一进行注释和扩展:
-
QuerydslPredicateExecutor
-
ReactiveQuerydslPredicateExecutor
-
QueryByExampleExecutor
-
ReactiveQueryByExampleExecutor
被 Spring Boot 检测到并被视为DataFetcher
匹配*查询的候选者。
6.4. 运输
6.4.1. HTTP 和 WebSocket
GraphQL HTTP 端点默认位于 HTTP POST "/graphql"。可以使用自定义路径spring.graphql.path
。
GraphQL WebSocket 端点默认关闭。要启用它:
- 对于 Servlet 应用程序,添加 WebSocket 启动器
spring-boot-starter-websocket
- 对于 WebFlux 应用程序,不需要额外的依赖项
- 对于两者,
spring.graphql.websocket.path
必须设置应用程序属性
Spring GraphQL 提供了一个Web 拦截模型。这对于从 HTTP 请求头中检索信息并将其设置在 GraphQL 上下文中或从同一上下文中获取信息并将其写入响应头中非常有用。使用 Spring Boot,您可以声明一个WebInterceptor
bean 以将其注册到 Web 传输。
Spring MVC和Spring WebFlux支持 CORS(跨域资源共享)请求。CORS 是 GraphQL 应用程序 Web 配置的关键部分,这些应用程序可以从使用不同域的浏览器访问。
Spring Boot 支持命名空间下的许多配置属性spring.graphql.cors.*
;这是一个简短的配置示例:
特性
6.4.2. RSocket
在 WebSocket 或 TCP 之上,RSocket 也被支持作为一种传输方式。一旦配置了 RSocket 服务器,我们就可以使用spring.graphql.rsocket.mapping
. 例如,将该映射配置为"graphql"
意味着我们可以在使用RSocketGraphQlClient
.
Spring Boot 自动配置一个RSocketGraphQlClient.Builder<?>
bean,您可以将其注入组件中:
然后发送请求:
6.5异常处理
Spring GraphQL 使应用程序能够注册一个或多个DataFetcherExceptionResolver
按顺序调用的 Spring 组件。异常必须解析为graphql.GraphQLError
对象列表,请参阅Spring GraphQL 异常处理文档。Spring Boot 将自动检测DataFetcherExceptionResolver
bean 并将它们注册到GraphQlSource.Builder
.
6.6. GraphiQL 和 Schema 打印机
Spring GraphQL 在使用或开发 GraphQL API 时提供了帮助开发人员的基础设施。
Spring GraphQL 附带一个默认公开的默认GraphiQL页面"/graphiql"
。此页面默认禁用,可以使用spring.graphql.graphiql.enabled
属性打开。许多公开此类页面的应用程序将更喜欢自定义构建。默认实现在开发过程中非常有用,这就是它spring-boot-devtools在开发过程中自动公开的原因。
您还可以选择在启用/graphql/schema
该spring.graphql.schema.printer.enabled
属性时以文本格式公开 GraphQL 架构。
7. 春天 HATEOAS
如果您开发使用超媒体的 RESTful API,Spring Boot 为 Spring HATEOAS 提供自动配置,适用于大多数应用程序。自动配置取代了使用@EnableHypermediaSupport
和注册许多 bean 以简化构建基于超媒体的应用程序的需要,包括一个LinkDiscoverers
(用于客户端支持)和一个ObjectMapper
配置为将响应正确编组为所需表示的配置。可以通过ObjectMapper
设置各种spring.jackson.*
属性来定制,或者,如果存在的话,可以通过Jackson2ObjectMapperBuilder
bean 来定制。
您可以使用 . 来控制 Spring HATEOAS 的配置@EnableHypermediaSupport
。请注意,这样做会禁用ObjectMapper
前面描述的自定义。
8.接下来要读什么
您现在应该对如何使用 Spring Boot 开发 Web 应用程序有了很好的了解。接下来的几节描述 Spring Boot 如何与各种数据技术、消息系统和其他 IO 功能集成。您可以根据应用程序的需要选择其中的任何一个。