SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

下一篇[未完待续]

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>英文原文:https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features-developing-web-applications/<code>
<code>GitHub:https://github.com/jijicai/Spring/tree/master/spring-boot/<code>

29.3、JAX-RS 和 Jersey

如果你喜欢 REST 端点的 JAX-RS 编程模型,则你可以使用其中一个可用的实现来代替 Spring MVC。Jersey 和 Apache CXF 的开箱即用效果非常好。CXF 要求你在应用程序上下文中将其 Servlet 或过滤器注册为 @Bean。Jersey 有一些本地的 Spring 支持,因此我们也在 Spring Boot 中为它提供自动配置支持,同时还提供了一个启动器(starter)。

要开始使用 Jersey,需要将 spring-boot-starter-jersey 作为依赖项,然后需要一个 ResourceConfig 类型的 @Bean,在其中注册所有端点,如下面示例所示:

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>@Componentpublic class JerseyConfig extends ResourceConfig {    public JerseyConfig() {        register(Endpoint.class);    }}/<code>

警告:Jersey 对扫描可执行文件(archives)的支持相当有限。例如,当运行可执行 war 文件时,它无法扫描在完全可执行 jar 文件或 WEB-INF/classes 中找到的包中的端点。为了避免这种限制,不应该使用 packages 方法,而应该使用 register 方法单独注册端点,如前一个示例所示。

对于更高级的定制,您还可以注册实现 ResourceConfigCustomizer 的任意数量的 bean。

所有注册的端点都应该是带有 HTTP 资源注解(@GET 和其他)的 @Components,如下面示例所示:

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>@Component@Path("/hello")public class Endpoint {    @GET    public String message() {        return "Hello";    }}/<code>

由于 Endpoint 是 Spring @Component,其生命周期由 Spring 管理,你可以使用 @Autowired 注解注入依赖项,并使用 @Value 注解注入外部配置。默认情况下,Jersey servlet 已注册并映射到 /*。你可以通过向 ResourceConfig 添加 @ApplicationPath 来更改映射。

默认情况下,Jersey 在一个名为 jerseyServletRegistration 的 ServletRegistrationBean 类型的 @Bean 中设置为一个 Servlet。默认情况下,servlet 是惰性初始化的,但是你可以通过设置 spring.jersey.servlet.load-on-startup 自定义该行为。你可以通过使用相同的名称创建自己的 bean 来禁用或重写该 bean。还可以通过设置 spring.jersey.type=filter 来使用过滤器而不是 servlet(在这种情况下,要替换或重写的 @Bean 是 jerseyFilterRegistration)。过滤器有一个 @Order,可以用 spring.jersey.filter.order 设置。通过使用 spring.jersey.init.* 指定属性映射,可以为 servlet 和过滤器注册提供 init 参数。

这里有一个 Jersey 示例,你可以看看如何设置。(https://github.com/spring-projects/spring-boot/tree/v2.1.6.RELEASE/spring-boot-samples/spring-boot-sample-jersey )

29.4、嵌入式 Servlet 容器支持

Spring Boot 包括对嵌入式 Tomcat、Jetty 和 Undertow 服务器的支持。大多数开发人员使用适当的“Starter”来获得完全配置的实例。默认情况下,嵌入式服务器监听端口 8080 上的 HTTP 请求。

29.4.1、Servlet、过滤器和监听器

使用嵌入式 servlet 容器时,可以使用 Spring beans 或通过扫描 Servlet 组件从 Servlet 规范注册 servlet、过滤器和所有监听器(例如:HttpSessionListener)。

将 Servlets、Filters 和 Listeners 注册为 Spring Beans

任何作为 Spring bean 的 Servlet、Filter 或 servlet* 监听器实例都会注册到嵌入式容器中。如果要在配置过程中引用 application.properties 中的值,这会特别方便。

默认情况下,如果上下文只包含一个 Servlet,则将其映射到 / 。在多个 servlet bean 的情况下,bean 名称用作路径前缀。过滤器映射到 /* 。

如果基于约定的映射不够灵活,则你可以使用 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 来完全控制。

Spring Boot 附带了许多可以定义 Filter bean 的自动配置。下面是一些 Filters 的示例及其各自的顺序(低阶值意味着更高的优先级):

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>Servlet FilterOrderOrderedCharacterEncodingFilterOrdered.HIGHEST_PRECEDENCEWebMvcMetricsFilterOrdered.HIGHEST_PRECEDENCE + 1ErrorPageFilterOrdered.HIGHEST_PRECEDENCE + 1HttpTraceFilterOrdered.LOWEST_PRECEDENCE - 10/<code>

通常情况下,不为 Filter beans 排序是安全的。

如果需要特定的顺序,则应避免配置以 Ordered.HIGHEST_PRECEDENCE 读取请求正文的 Filter,因为它可能违反应用程序的字符编码配置。如果 Servlet 过滤器包装请求,则应该使用小于或等于 OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER 的顺序对其进行配置。

29.4.2、Servlet 上下文初始化

嵌入式 servlet 容器不会直接执行 Servlet 3.0+ 的 javax.servlet.ServletContainerInitializer 接口或 Spring 的 org.springframework.web.WebApplicationInitializer 接口。这是一个有意的设计决策,旨在降低设计用于在 war 中运行的第三方库可能会破坏 Spring Boot 应用程序的风险。

如果需要在 Spring Boot 应用程序中执行 servlet 上下文初始化,则应注册实现 org.springframework.boot.web.servlet.ServletContext 接口的 bean。单个 onStartup 方法提供对 ServletContext 的访问,如果需要,可以很容易地将其用作现有 WebApplicationInitializer 的适配器。

扫描 Servlets、Filters 和 监听器

在使用嵌入式容器时,可以通过使用 @ServletComponentScan 启用 @WebServlet、@WebFilter 和 @WebListener 注解的类的自动注册。

提示:@ServletComponentScan 在一个独立的容器中不起作用,它使用容器的内置发现机制。

29.4.3、ServletWebServerApplicationContext

在底层,Spring Boot 使用不同类型的 ApplicationContext 来支持嵌入式 servlet 容器。ServletWebServerApplicationContext 是一种特殊类型的 WebApplicationContext,它通过搜索单个 ServletWebServerFactory bean 来引导自己。通常,TomcatServletWebServerFactory、JettyServletWebServerFactory 或 UndertowServletWebServerFactory 已自动配置。

注释:你通常不需要知道这些实现类。大多数应用程序是自动配置的,适当的 ApplicationContext 和 ServletWebServerFactory 是代表你创建的。

29.4.4、自定义嵌入式 Servlet 容器

可以使用 Spring Environment 属性配置常用的 servlet 容器设置。通常,你会在 application.properties 文件中定义属性。

常用服务器设置包括:

(1)网络设置:监听传入 HTTP 请求的端口(server.port),绑定到 server.address 的接口地址,等等。

(2)会话设置:会话是否持久(server.servlet.session.persistence)、会话超时(server.servlet.session.timeout)、会话数据位置(server.servlet.session.store-dir)、和 session-cookie 配置(server.servlet.session.cookie.*)。

(3)错误管理:错误页的位置(server.error.path)等。

(4)SSL(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-embedded-web-servers.html#howto-configure-ssl )

(5)HTTP 压缩(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-embedded-web-servers.html#how-to-enable-http-response-compression )

Spring Boot 尽可能多地尝试公开公共设置,但这并不总是可能的。对于这些情况,专用名称空间提供特定于服务器的定制(请参阅 server.tomcat 和 server.undertow)。例如,可以使用嵌入式 servlet 容器的特定功能配置访问日志。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/howto-embedded-web-servers.html#howto-configure-accesslogs )

提示:有关完整列表,请参见 ServerProperties 类。(https://github.com/spring-projects/spring-boot/tree/v2.1.6.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java )

程序化定制

如果需要以编程方式配置嵌入式 servlet 容器,可以注册实现 WebServerFactoryCustomizer 接口的 Spring bean。WebServerFactoryCustomizer 提供对 ConfigurableServletWebServerFactory 的访问,其中包括许多自定义 setter 方法。以下示例显示了以编程方式设置端口:

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>import org.springframework.boot.web.server.WebServerFactoryCustomizer;import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;import org.springframework.stereotype.Component;@Componentpublic class CustomizationBean implements WebServerFactoryCustomizer<configurableservletwebserverfactory> {    @Override    public void customize(ConfigurableServletWebServerFactory server) {        server.setPort(9000);    }}/<configurableservletwebserverfactory>/<code>

注释:TomcatServletWebServerFactory、JettyServletWebServerFactory 和 UndertowServletWebServerFactory 是ConfigurableServletWebServerFactory 的专用变体,它们分别为 Tomcat、Jetty 和 Undertow 提供了额外的定制 setter 方法。

直接自定义 ConfigurableServletWebServerFactory

如果前面的定制技术太有限,你可以自己注册 TomcatServletWebServerFactory、JettyServletWebServerFactory 或 UndertowServletWebServerFactory bean。

SpringBoot中文参考指南(2.1.6)29.3、JAX-RS 和 Jersey

<code>@Beanpublic 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;}/<code>

为许多配置选项提供了 setter。如果你需要做一些更奇特的事情,还提供了几个受保护的方法钩子。有关详细信息,请参阅源码文档。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/api/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.html )

29.4.5、JSP 限制

当运行使用嵌入式 servlet 容器(并打包为可执行归档文件)的 Spring Boot 应用程序时,JSP 支持有一些限制。

(1)对于 Jetty 和 Tomcat,如果使用 war 包装,它应该可以工作。一个可执行的 war 在用 java-jar 启动时可以工作,并且可以部署到任何标准容器。使用可执行 jar 时不支持 JSP。

(2)Undertow 不支持 JSP。

(3)创建自定义 error.jsp 页面不会覆盖默认的错误处理视图。应该使用自定义错误页面。

这里有一个 JSP 示例,以便你了解如何进行设置。(https://github.com/spring-projects/spring-boot/tree/v2.1.6.RELEASE/spring-boot-samples/spring-boot-sample-web-jsp )

29.5、嵌入式反应式 Server 支持

Spring Boot 包括对以下嵌入式反应式 web 服务器的支持:Reactor Netty、Tomcat、Jetty和Undertow。大多数开发人员使用适当的“Starter”来获得完全配置的实例。默认情况下,嵌入式服务器监听端口 8080 上的 HTTP 请求。

29.6、反应式 Server 资源配置

当自动配置 Reactor Netty 或 Jetty 服务器时,Spring Boot 将创建特定的 bean,为服务器实例:ReactorResourceFactory 或 JettyResourceFactory ,提供 HTTP 资源。

默认情况下,这些资源还将与 Reactor Netty 和 Jetty 客户端共享,以获得最佳性能,前提是:

(1)服务器和客户端使用相同的技术。

(2)客户端实例是使用由 Spring Boot 自动配置的 WebClient.Builder bean 构建的。

开发者可以通过提供自定义的 ReactorResourceFactory 或 JettyResourceFactory bean 来覆盖Jetty 和 Reactor Netty 的资源配置-这将应用于客户端和服务器。

你可以在 WebClient Runtime 章节中了解有关客户端资源配置的更多信息。(https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-webclient.html#boot-features-webclient-runtime )

下一篇[未完待续]


分享到:


相關文章: