27.4 Embedded Servlet Container Support
Spring Boot包括对嵌入式Tomcat、Jetty和Undertow服务器的支持.
大多数开发人员使用适当的“Starters”获得一个完全配置实例.默认情况下,嵌入式服务器在端口8080
上侦听HTTP请求。
Warning
如果您选择在CentOS上使用Tomcat,请注意,在默认情况下,一个临时目录用于存储编译的jsp文件,上传的文件等等.这个目录可能在应用程序运行时被
tmpwatch
删除,这将导致运行失败. 为了避免这种情况,你可能想要定制tmpwatch
配置确保tomcat.*
目录不被删除或配置server.tomcat.basedir
使得嵌入的Tomcat使用不同的路径.
Servlets,Filters,and Listeners
当使用一个内嵌的servlet容器时,你可以按照servlet规范注册servlet,filters(过滤器)和所有的listeners(监听器)(如HttpSessionListener
),可通过使用Spring实例或servlet组件扫描方式.
Registering Servlets,Filters,and Listeners as Spring Beans
任何Servlet
,Filter
或Servlet *Listener
实例都将随嵌入式容器注册为Spring实例.在配置属性时,引用application.properties
中的属性值时将显得特别方便.
默认情况下,如果上下文只包含单例Servlet,则将其映射到/.对于多个servlet实例,实例名称将作为路径前缀,过滤器将被映射到/*.
如果基于约定的映射配置不够灵活,您可以使用ServletRegistrationBean
,FilterRegistrationBean
和ServletListenerRegistrationBean
类完全定制.
Spring Boot附带了许多自动配置可定义过滤器实例.这里有一些过滤器和各自顺序(低阶值意味着更高的优先级)的例子:
Servlet Filter | Order |
---|---|
OrderedCharacterEncodingFilter | Ordered.HIGHEST_PRECEDENCE |
WebMvcMetricsFilter | Ordered.HIGHEST_PRECEDENCE + 1 |
ErrorPageFilter | Ordered.HIGHEST_PRECEDENCE + 1 |
HttpTraceFilter | Ordered.LOWEST_PRECEDENCE - 10 |
通常安全的做法是让过滤器Bean实例无序.
如果需要特定的顺序,你应该避免配置一个过滤器使用Ordered.HIGHEST_PRECEDENCE
顺序值读取请求主体,因为它可能会不利于您的应用程序字符编码配置.
如果一个Servlet过滤器包装请求,该过滤器配置的顺序值应该小于或等于FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER
值.
Servlet Context Initialization
嵌入的servlet容器不会直接执行Servlet 3.0+规范的javax.servlet.ServletContainerInitializer
接口或Spring的org.springframework.web.WebApplicationInitializer
接口.
这是一个故意设计决策旨在降低第三方库在war中运行可能会破坏Spring Boot应用的风险.
如果需要在Spring Boot应用中执行servlet上下文初始化,您应该注册一个实现org.springframework.boot.web.servlet.ServletContextInitializer
接口的Bean实例.
该接口单一的onStartup
方法提供对ServletContext
的访问,并且,如果需要的话,很容易用作现有WebApplicationInitializer
的适配器.
Scanning for Servlets, Filters, and listeners
使用嵌入式容器时,使用@WebServlet
,@WebFilter
,@WebListener
注解的自动注册类可通过@ServletComponentScan
扫描启用.
Tip
@ServletComponentScan在一个独立的容器中没有影响,因为容器的内置发现机制默认替代了该使用方式.
The ServletWebServerApplicationContext
根据容器引擎不同,Spring Boot使用不同类型的ApplicationContext
支持嵌入servlet容器.ServletWebServerApplicationContext
是特殊类型的WebApplicationContext
,
它通过搜索单例的ServletWebServerFactory
来启动上下文.通常TomcatServletWebServerFactory
,JettyServletWebServerFactory
或UndertowServletWebServerFactory
是自动配置的.
Note
您通常不需要关注这些实现类.大多数应用程序是自动配置的且适当的
ApplicationContext
和ServletWebServerFactory
将根据你的行为创建.
Customizing Embedded Servlet Containers
可以使用Spring环境属性配置公共servlet容器设置.通常,你会在application.properties文件中定义属性.
常见的服务器设置包括:
- 网络设置:监听HTTP请求的端口(
server.port
), 接口地址绑定在server.address
等等. - Session设置:session是否持久化(
server.servlet.session.persistence
),session超时(server.servlet.session.timeout
),session数据保存路径(server.servlet.session.store-dir
)以及session-cookie配置(server.servlet.session.cookie.*
). - 错误管理:错误页面的路径(server.error.path)等等.
- SSL.
- HTTP连接.
Spring Boot尝试尽可能多地暴露这些公共设置,但这并不总是可能的.在某些情况下,专用名称空间提供特定于服务器的定制(见server.tomcat
和server.undertow
).
例如,访问日志可以为特定功能的嵌入servlet容器配置.
Tip
查看ServerProperties来获取完整参数列表.
Programmatic Customization
如果你需要以编程方式配置嵌入servlet容器,你可以注册一个实现WebServerFactoryCustomizer
接口的Spring Bean实例.
WebServerFactoryCustomizer
为ConfigurableServletWebServerFactory
提供访问接入点,其中包括许多定制的setter方法.Tomcat、Jetty和Undertow都有专用的变量.下面的例子展示了以编程方式设置端口:
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
Customizing ConfigurableServletWebServerFactory Directly
如果上述的配置技术太过于局限,你可以创建你自己的TomcatServletWebServerFactory
,JettyServletWebServerFactory
,UnderowServletWebServerFactory
Bean实例进行注册:
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));
return factory;
}
许多配置选项都提供了setter.大量的保护方法“钩子”也提供,便于你需要作更多奇异的更改.有关详细信息,请参阅源代码文档.
JSP Limitations
当使用嵌入式servlet容器运行Spring Boot应用程序(或打包为一个可执行归档)时,在JSP支持上存在如下限制:
- 对于Tomcat,如果您使用war包,则应该可以运行.换言之,一个可执行的war包也可部署到一个标准容器(不限于,但包括Tomcat).由于Tomcat的硬编码的文件模式,一个可执行jar不能正常工作.
- 对于Jetty来说,如果您使用war包,则应该可以运行.换言之,一个可执行的war包也可部署到一个标准容器.
- Undertow不支持jsp.
- 创建一个自定义的
error.jsp
页面不会覆盖错误处理的默认视图.应该使用自定义的错误页面.
可参阅JSP示例,获取如何设置.