8.1.3. 嵌入式 Servlet 容器支持
对于 servlet 应用程序,Spring Boot 包括对嵌入式Tomcat、Jetty和Undertow服务器的支持。大多数开发人员使用适当的“Starter”来获取完全配置的实例。默认情况下,嵌入式服务器侦听端口 8080
上的 HTTP 请求。
Servlet、过滤器和侦听器
使用嵌入式 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 bean保持无序状态是安全的。如果需要特定的顺序,您应该使用@Order
注释Filter
或使其实现Ordered
。您不能通过使用@Order
注释其 bean 方法来配置Filter
的顺序。如果您无法为Filter
添加@Order
或实现的类Ordered
,则必须为Filter
定义FilterRegistrationBean
并使用 setOrder(int)
方法设置注册 bean 的顺序。避免配置在 Ordered.HIGHEST_PRECEDENCE
处读取请求正文的过滤器,因为它可能会违反应用程序的字符编码配置。如果 servlet 过滤器包装请求,则应配置小于或等于 OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER
的顺序。
要查看应用程序中 每个
Filter
项的顺序,请为web
日志记录组(logging.level.web=debug
) 启用调试级别日志记录。已注册过滤器的详细信息(包括它们的顺序和 URL 模式)将在启动时记录下来。注册
Filter
bean 时要小心,因为它们是在应用程序生命周期的早期初始化的。如果您需要注册Filter
与其他 bean 交互,请考虑使用DelegatingFilterProxyRegistrationBean
来代替。
Servlet 上下文初始化
嵌入式servlet容器不直接执行jakarta.servlet.ServletContainerInitializer
接口或Spring的org.springframework.web.WebApplicationInitializer
接口。这是一个有意的设计决策,旨在降低设计用于在战争中运行的第三方库可能破坏 Spring Boot 应用程序的风险。
如果需要在 Spring Boot 应用程序中执行 servlet 上下文初始化,则应该注册一个实现org.springframework.boot.web.servlet.ServletContextInitializer
接口的 bean。单一onStartup
方法提供对 ServletContext
的访问,并且如果需要,可以轻松地用作现有WebApplicationInitializer
的适配器.
扫描 Servlet、过滤器和侦听器
使用嵌入式容器时,可以使用 @ServletComponentScan
启用自动注册用@WebServlet
、@WebFilter
、 和@WebListener
注释的类。
@ServletComponentScan
在独立容器中没有效果,由于它使用容器的内置发现机制。
ServletWebServerApplicationContext
在底层,Spring Boot 使用不同类型的ApplicationContext
提供嵌入式 servlet 容器支持。ServletWebServerApplicationContext
是一种特殊类型WebApplicationContext
,它通过搜索单个ServletWebServerFactory
bean 来引导自身。通常TomcatServletWebServerFactory
、JettyServletWebServerFactory
、 或UndertowServletWebServerFactory
都会被自动配置。
您通常不需要了解这些实现类。大多数应用程序都是自动配置的,并且会代表您创建适当的
ApplicationContext
和ServletWebServerFactory
。
在嵌入式容器设置中,ServletContext
被设置为服务器启动的一部分,该启动在应用程序上下文初始化期间发生。因此,ApplicationContext
不能使用 ServletContext
初始化中的 beans 。解决这个问题的一种方法是ApplicationContext
作为 bean 的依赖项注入并ServletContext
仅在需要时访问。另一种方法是在服务器启动后使用回调。这可以使用ApplicationListener
监听ApplicationStartedEvent
来完成,如下所示:
自定义嵌入式 Servlet 容器
常见的 servlet 容器设置可以使用 SpringEnvironment
属性进行配置。通常,您可以在您的application.properties
或application.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
)等。
Spring Boot 尝试尽可能多地公开通用设置,但这并不总是可行。对于这些情况,专用命名空间提供特定于服务器的自定义(请参阅server.tomcat
和server.undertow
)。例如,可以使用嵌入式 servlet 容器的特定功能来配置访问日志。
请参阅
ServerProperties
课程以获取完整列表。
同站点 Cookie
Web 浏览器可以使用cookie属性SameSite
来控制在跨站点请求中是否提交 cookie 以及如何提交。该属性与现代 Web 浏览器特别相关,现代 Web 浏览器已开始更改该属性丢失时使用的默认值。
如果您想更改会话 cookie 的SameSite
属性,可以使用server.servlet.session.cookie.same-site
属性。自动配置的 Tomcat、Jetty 和 Undertow 服务器支持此属性。它还用于配置基于 Spring Session servlet 的SessionRepository
bean。
例如,如果您希望会话 cookie 具有None
值的SameSite
属性,您可以将以下内容添加到您的application.properties
或application.yaml
文件中:
如果您想更改SameSite
添加到您的其他 cookie 上的属性HttpServletResponse
,您可以使用CookieSameSiteSupplier
. CookieSameSiteSupplier
传递 a并Cookie
可能返回一个SameSite
值,或null
。
您可以使用许多便利的工厂和过滤器方法来快速匹配特定的 cookie。例如,添加以下 bean 将自动为名称与正则表达式 myapp.*
匹配的所有cookie
应用 Lax
的 SameSite
。
字符编码
可以使用配置server.servlet.encoding.*
属性来配置用于请求和响应处理的嵌入式 Servlet 容器的字符编码行为。
当请求的Accept-Language
标头指示请求的区域设置时,servlet 容器将自动将其映射到字符集。每个容器都提供默认区域设置到字符集映射,您应该验证它们是否满足您的应用程序的需求。如果不存在,请使用server.servlet.encoding.mapping
配置属性来自定义映射,如以下示例所示:
在前面的示例中,ko
(韩语)区域设置已映射到UTF-8
. 这相当于传统war部署文件web.xml
中的<locale-encoding-mapping-list>
条目。
程序化定制
如果您需要以编程方式配置嵌入式 servlet 容器,您可以注册一个实现WebServerFactoryCustomizer
接口的 Spring bean。 WebServerFactoryCustomizer
提供对ConfigurableServletWebServerFactory
的访问,其中包括许多自定义设置器方法。以下示例显示以编程方式设置端口:
TomcatServletWebServerFactory
、JettyServletWebServerFactory
和UndertowServletWebServerFactory
是其专用变体,ConfigurableServletWebServerFactory
分别为 Tomcat、Jetty 和 Undertow 提供额外的自定义 setter 方法。以下示例显示如何进行自定义TomcatServletWebServerFactory
以提供对特定于 Tomcat 的配置选项的访问:
直接自定义 ConfigurableServletWebServerFactory
对于需要从 扩展的更高级用例ServletWebServerFactory
,您可以自己公开此类类型的 bean。
为许多配置选项提供了设置器。如果您需要做一些更奇特的事情,还提供了几个受保护的方法“挂钩”。详细信息请参见源代码文档。
自动配置的定制器仍然应用于您的定制工厂,因此请谨慎使用该选项。
JSP 限制
当运行使用嵌入式 servlet 容器(并打包为可执行存档)的 Spring Boot 应用程序时,JSP 支持存在一些限制。
对于 Jetty 和 Tomcat,如果您使用 war 包装,它应该可以工作。可执行的 war 在使用
java -jar
启动时可以工作,并且也可以部署到任何标准容器。使用可执行 jar 时不支持 JSP。Undertow 不支持 JSP。
最后更新于