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 )

下一篇[未完待續]


分享到:


相關文章: