嵌入式 Web 伺服器
每個 Spring Boot Web 應用程式都包含一個嵌入式 Web 伺服器。此功能引發許多操作指南問題,包括如何變更嵌入式伺服器以及如何組態嵌入式伺服器。本節回答這些問題。
使用其他 Web 伺服器
許多 Spring Boot Starter 包含預設的嵌入式容器。
-
對於 Servlet 堆疊應用程式,
spring-boot-starter-web
透過包含spring-boot-starter-tomcat
來包含 Tomcat,但您可以使用spring-boot-starter-jetty
或spring-boot-starter-undertow
來替代。 -
對於反應式堆疊應用程式,
spring-boot-starter-webflux
透過包含spring-boot-starter-reactor-netty
來包含 Reactor Netty,但您可以使用spring-boot-starter-tomcat
、spring-boot-starter-jetty
或spring-boot-starter-undertow
來替代。
當切換到不同的 HTTP 伺服器時,您需要將預設的依賴項替換為您需要的依賴項。為了幫助您完成此過程,Spring Boot 為每個支援的 HTTP 伺服器提供了一個獨立的 Starter。
以下 Maven 範例展示如何排除 Tomcat 並包含 Jetty 以用於 Spring MVC
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
以下 Gradle 範例組態必要的依賴項和 模組替換,以在 Spring WebFlux 中使用 Undertow 取代 Reactor Netty
dependencies {
implementation "org.springframework.boot:spring-boot-starter-undertow"
implementation "org.springframework.boot:spring-boot-starter-webflux"
modules {
module("org.springframework.boot:spring-boot-starter-reactor-netty") {
replacedBy("org.springframework.boot:spring-boot-starter-undertow", "Use Undertow instead of Reactor Netty")
}
}
}
使用 WebClient 類別需要 spring-boot-starter-reactor-netty ,因此即使您需要包含不同的 HTTP 伺服器,您也可能需要保留對 Netty 的依賴。 |
停用 Web 伺服器
如果您的類別路徑包含啟動 Web 伺服器所需的位元,Spring Boot 將自動啟動它。若要停用此行為,請在您的 application.properties
中組態 WebApplicationType
,如下列範例所示
-
屬性
-
YAML
spring.main.web-application-type=none
spring:
main:
web-application-type: "none"
變更 HTTP Port
在獨立應用程式中,主要的 HTTP Port 預設為 8080
,但可以使用 server.port
(例如,在 application.properties
中或作為系統屬性) 進行設定。由於 Environment
值的寬鬆綁定,您也可以使用 SERVER_PORT
(例如,作為 OS 環境變數)。
若要完全關閉 HTTP 端點,但仍建立 WebApplicationContext
,請使用 server.port=-1
(這樣做有時對於測試很有用)。
如需更多詳細資訊,請參閱 ‘Spring Boot Features’ 區段中的 自訂嵌入式 Servlet 容器,或 ServerProperties
類別。
在執行階段探索 HTTP Port
您可以從記錄輸出或從 WebServerApplicationContext
透過其 WebServer
存取伺服器正在執行的 Port。取得該 Port 並確保已初始化的最佳方法是新增類型為 ApplicationListener<WebServerInitializedEvent>
的 @Bean
,並在發布事件時從事件中拉出容器。
使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
的測試也可以使用 @LocalServerPort
註解將實際 Port 注入到欄位中,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {
@LocalServerPort
int port;
// ...
}
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.server.LocalServerPort
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyWebIntegrationTests {
@LocalServerPort
var port = 0
// ...
}
|
啟用 HTTP 回應壓縮
Jetty、Tomcat、Reactor Netty 和 Undertow 支援 HTTP 回應壓縮。可以在 application.properties
中啟用它,如下所示
-
屬性
-
YAML
server.compression.enabled=true
server:
compression:
enabled: true
預設情況下,回應長度必須至少為 2048 位元組才能執行壓縮。您可以透過設定 server.compression.min-response-size
屬性來組態此行為。
預設情況下,僅當回應的內容類型為下列其中一種時,才會壓縮回應
-
text/html
-
text/xml
-
text/plain
-
text/css
-
text/javascript
-
application/javascript
-
application/json
-
application/xml
您可以透過設定 server.compression.mime-types
屬性來組態此行為。
組態 SSL
可以透過設定各種 server.ssl.*
屬性以宣告方式組態 SSL,通常在 application.properties
或 application.yaml
中。請參閱 Ssl
以取得所有支援屬性的詳細資訊。
下列範例顯示使用 Java KeyStore 檔案設定 SSL 屬性
-
屬性
-
YAML
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=secret
server.ssl.key-password=another-secret
server:
port: 8443
ssl:
key-store: "classpath:keystore.jks"
key-store-password: "secret"
key-password: "another-secret"
使用如前述範例的組態表示應用程式不再支援 Port 8080 上的純 HTTP 連接器。Spring Boot 不支援透過 application.properties
組態 HTTP 連接器和 HTTPS 連接器兩者。如果您想要兩者都有,您需要以程式設計方式組態其中一個。我們建議使用 application.properties
來組態 HTTPS,因為 HTTP 連接器是兩者中較容易以程式設計方式組態的連接器。
使用 PEM 編碼檔案
您可以使用 PEM 編碼檔案來替代 Java KeyStore 檔案。您應盡可能使用 PKCS#8 金鑰檔案。PEM 編碼的 PKCS#8 金鑰檔案以 -----BEGIN PRIVATE KEY-----
或 -----BEGIN ENCRYPTED PRIVATE KEY-----
標頭開頭。
如果您有其他格式的檔案,例如 PKCS#1 (-----BEGIN RSA PRIVATE KEY-----
) 或 SEC 1 (-----BEGIN EC PRIVATE KEY-----
),您可以使用 OpenSSL 將它們轉換為 PKCS#8
openssl pkcs8 -topk8 -nocrypt -in <input file> -out <output file>
下列範例顯示使用 PEM 編碼憑證和私密金鑰檔案設定 SSL 屬性
-
屬性
-
YAML
server.port=8443
server.ssl.certificate=classpath:my-cert.crt
server.ssl.certificate-private-key=classpath:my-cert.key
server.ssl.trust-certificate=classpath:ca-cert.crt
server:
port: 8443
ssl:
certificate: "classpath:my-cert.crt"
certificate-private-key: "classpath:my-cert.key"
trust-certificate: "classpath:ca-cert.crt"
使用 SSL Bundle
或者,可以在 SSL bundle 中組態 SSL 信任材料,並將其套用於 Web 伺服器,如此範例所示
-
屬性
-
YAML
server.port=8443
server.ssl.bundle=example
server:
port: 8443
ssl:
bundle: "example"
server.ssl.bundle 屬性不能與 server.ssl 下的離散 Java KeyStore 或 PEM 屬性選項結合使用。 |
組態伺服器名稱指示
可以將 Tomcat、Netty 和 Undertow 組態為針對個別主機名稱使用唯一的 SSL 信任材料,以支援伺服器名稱指示 (SNI)。Jetty 不支援 SNI 組態,但如果向 Jetty 提供多個憑證,Jetty 可以自動設定 SNI。
假設已組態名為 web
、web-alt1
和 web-alt2
的 SSL bundle,則可以使用下列組態將每個 bundle 指派給嵌入式 Web 伺服器服務的主機名稱
-
屬性
-
YAML
server.port=8443
server.ssl.bundle=web
server.ssl.server-name-bundles[0].server-name=alt1.example.com
server.ssl.server-name-bundles[0].bundle=web-alt1
server.ssl.server-name-bundles[1].server-name=alt2.example.com
server.ssl.server-name-bundles[1].bundle=web-alt2
server:
port: 8443
ssl:
bundle: "web"
server-name-bundles:
- server-name: "alt1.example.com"
bundle: "web-alt1"
- server-name: "alt2.example.com"
bundle: "web-alt2"
使用 server.ssl.bundle
指定的 bundle 將用於預設主機,以及任何不支援 SNI 的用戶端。如果已組態任何 server.ssl.server-name-bundles
,則必須組態此預設 bundle。
組態 HTTP/2
您可以使用 server.http2.enabled
組態屬性在您的 Spring Boot 應用程式中啟用 HTTP/2 支援。h2
(透過 TLS 的 HTTP/2) 和 h2c
(透過 TCP 的 HTTP/2) 都受到支援。若要使用 h2
,也必須啟用 SSL。當未啟用 SSL 時,將使用 h2c
。例如,當您的應用程式 在執行 TLS 終止的 Proxy 伺服器後方執行 時,您可能想要使用 h2c
。
Tomcat 的 HTTP/2
Spring Boot 預設隨附 Tomcat 10.1.x,該版本開箱即用支援 h2c
和 h2
。或者,如果程式庫及其依賴項安裝在主機作業系統上,您可以將 libtcnative
用於 h2
支援。
如果尚未提供程式庫目錄,則必須將其提供給 JVM 程式庫路徑。您可以使用 JVM 引數 (例如 -Djava.library.path=/usr/local/opt/tomcat-native/lib
) 來執行此操作。如需更多資訊,請參閱 官方 Tomcat 文件。
Jetty 的 HTTP/2
為了支援 HTTP/2,Jetty 需要額外的 org.eclipse.jetty.http2:jetty-http2-server
依賴項。若要使用 h2c
,則不需要其他依賴項。若要使用 h2
,您還需要選擇下列其中一個依賴項,具體取決於您的部署
-
org.eclipse.jetty:jetty-alpn-java-server
以使用 JDK 內建支援 -
org.eclipse.jetty:jetty-alpn-conscrypt-server
和 Conscrypt 程式庫
Reactor Netty 的 HTTP/2
spring-boot-webflux-starter
預設使用 Reactor Netty 作為伺服器。Reactor Netty 開箱即用支援 h2c
和 h2
。為了獲得最佳執行階段效能,此伺服器也支援使用原生程式庫的 h2
。若要啟用此功能,您的應用程式需要額外的依賴項。
Spring Boot 管理 io.netty:netty-tcnative-boringssl-static
"uber jar" 的版本,其中包含所有平台的原生程式庫。開發人員可以選擇僅匯入使用分類器的必要依賴項 (請參閱 Netty 官方文件)。
組態 Web 伺服器
通常,您應首先考慮使用許多可用的組態金鑰之一,並透過在您的 application.properties
或 application.yaml
檔案中新增新項目來自訂您的 Web 伺服器。請參閱 探索外部屬性的內建選項)。server.*
命名空間在此非常有用,它包含例如 server.tomcat.*
、server.jetty.*
和其他伺服器特定功能的命名空間。請參閱 常用應用程式屬性 列表。
先前的章節已涵蓋許多常見的使用案例,例如壓縮、SSL 或 HTTP/2。但是,如果您的使用案例不存在組態金鑰,則您應查看 WebServerFactoryCustomizer
。您可以宣告此類元件並存取與您的選擇相關的伺服器 Factory:您應針對選定的伺服器 (Tomcat、Jetty、Reactor Netty、Undertow) 和選定的 Web 堆疊 (Servlet 或反應式) 選擇變體。
以下範例適用於搭配 spring-boot-starter-web
(Servlet 堆疊) 的 Tomcat
-
Java
-
Kotlin
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
@Component
public class MyTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
// customize the factory here
}
}
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.stereotype.Component
@Component
class MyTomcatWebServerCustomizer : WebServerFactoryCustomizer<TomcatServletWebServerFactory?> {
override fun customize(factory: TomcatServletWebServerFactory?) {
// customize the factory here
}
}
Spring Boot 在內部使用該基礎架構來自動組態伺服器。自動組態的 WebServerFactoryCustomizer Bean 的順序為 0 ,並且會在任何使用者定義的自訂工具之前處理,除非它具有明確指示的其他順序。 |
一旦您使用自訂工具存取 WebServerFactory
,您就可以使用它來組態特定部分,例如連接器、伺服器資源或伺服器本身 - 全部使用伺服器特定的 API。
此外,Spring Boot 還提供
伺服器 | Servlet 堆疊 | 反應式堆疊 |
---|---|---|
Tomcat |
|
|
Jetty |
|
|
Undertow |
|
|
Reactor |
N/A |
|
作為最後手段,您也可以宣告您自己的 WebServerFactory
Bean,它將覆寫 Spring Boot 提供的 Bean。當您這樣做時,自動組態的自訂工具仍會套用於您的自訂 Factory,因此請謹慎使用該選項。
將 Servlet、Filter 或 Listener 新增到應用程式
在 Servlet 堆疊應用程式中,也就是使用 spring-boot-starter-web
,有兩種方法可以將 Servlet
、Filter
、ServletContextListener
和 Servlet API 支援的其他 Listener 新增到您的應用程式
透過使用 Spring Bean 新增 Servlet、Filter 或 Listener
若要透過使用 Spring Bean 新增 Servlet
、Filter
或 Servlet *Listener
,您必須為其提供 @Bean
定義。當您想要注入組態或依賴項時,這樣做非常有用。但是,您必須非常小心,它們不會導致過多其他 Bean 的急切初始化,因為它們必須在應用程式生命週期的早期安裝在容器中。(例如,讓它們依賴您的 DataSource
或 JPA 組態不是一個好主意。) 您可以透過在首次使用時而不是在初始化時延遲初始化 Bean 來解決此類限制。
在 Filter 和 Servlet 的情況下,您也可以透過新增 FilterRegistrationBean
或 ServletRegistrationBean
來替代或補充底層元件,從而新增映射和初始化參數。
如果在 Filter 註冊上未指定 |
與任何其他 Spring Bean 一樣,您可以定義 Servlet Filter Bean 的順序;請務必查看 將 Servlet、Filter 和 Listener 註冊為 Spring Bean 區段。
停用 Servlet 或 Filter 的註冊
如先前所述,任何 Servlet
或 Filter
Bean 都會自動向 Servlet 容器註冊。若要停用特定 Filter
或 Servlet
Bean 的註冊,請為其建立註冊 Bean 並將其標記為已停用,如下列範例所示
-
Java
-
Kotlin
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {
@Bean
public FilterRegistrationBean<MyFilter> registration(MyFilter filter) {
FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(filter);
registration.setEnabled(false);
return registration;
}
}
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyFilterConfiguration {
@Bean
fun registration(filter: MyFilter): FilterRegistrationBean<MyFilter> {
val registration = FilterRegistrationBean(filter)
registration.isEnabled = false
return registration
}
}
組態存取記錄
可以透過其各自的命名空間為 Tomcat、Undertow 和 Jetty 組態存取記錄。
例如,下列設定使用 自訂模式 在 Tomcat 上記錄存取。
-
屬性
-
YAML
server.tomcat.basedir=my-tomcat
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%t %a %r %s (%D microseconds)
server:
tomcat:
basedir: "my-tomcat"
accesslog:
enabled: true
pattern: "%t %a %r %s (%D microseconds)"
記錄的預設位置是相對於 Tomcat 基底目錄的 logs 目錄。預設情況下,logs 目錄是一個臨時目錄,因此您可能想要修正 Tomcat 的基底目錄或使用記錄的絕對路徑。在先前的範例中,記錄在相對於應用程式工作目錄的 my-tomcat/logs 中可用。 |
可以類似的方式組態 Undertow 的存取記錄,如下列範例所示
-
屬性
-
YAML
server.undertow.accesslog.enabled=true
server.undertow.accesslog.pattern=%t %a %r %s (%D milliseconds)
server.undertow.options.server.record-request-start-time=true
server:
undertow:
accesslog:
enabled: true
pattern: "%t %a %r %s (%D milliseconds)"
options:
server:
record-request-start-time: true
請注意,除了啟用存取記錄和組態其模式之外,還啟用了記錄請求開始時間。當在存取記錄模式中包含回應時間 (%D
) 時,這是必要的。記錄儲存在相對於應用程式工作目錄的 logs
目錄中。您可以透過設定 server.undertow.accesslog.dir
屬性來自訂此位置。
最後,也可以如下組態 Jetty 的存取記錄
-
屬性
-
YAML
server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log
server:
jetty:
accesslog:
enabled: true
filename: "/var/log/jetty-access.log"
預設情況下,記錄會重新導向到 System.err
。如需更多詳細資訊,請參閱 Jetty 文件。
在前端 Proxy 伺服器後方執行
如果您的應用程式在 Proxy、負載平衡器或雲端中執行,則請求資訊 (例如主機、Port、Scheme...) 可能會沿途變更。您的應用程式可能在 10.10.10.10:8080
上執行,但 HTTP 用戶端應僅看到 example.org
。
RFC7239 "Forwarded Headers" 定義了 Forwarded
HTTP 標頭;Proxy 可以使用此標頭來提供有關原始請求的資訊。您可以組態您的應用程式以讀取這些標頭,並在建立連結並在 HTTP 302 回應、JSON 文件或 HTML 頁面中將它們傳送給用戶端時自動使用該資訊。還有非標準標頭,例如 X-Forwarded-Host
、X-Forwarded-Port
、X-Forwarded-Proto
、X-Forwarded-Ssl
和 X-Forwarded-Prefix
。
如果 Proxy 新增常用的 X-Forwarded-For
和 X-Forwarded-Proto
標頭,則將 server.forward-headers-strategy
設定為 NATIVE
就足以支援這些標頭。使用此選項,Web 伺服器本身原生支援此功能;您可以查看其特定文件以了解特定行為。
如果這還不夠,Spring Framework 為 Servlet 堆疊提供了 ForwardedHeaderFilter,為反應式堆疊提供了 ForwardedHeaderTransformer。您可以透過將 server.forward-headers-strategy
設定為 FRAMEWORK
在您的應用程式中使用它們。
如果您正在使用 Tomcat 並在 Proxy 終止 SSL,則應將 server.tomcat.redirect-context-root 設定為 false 。這允許在執行任何重新導向之前先採用 X-Forwarded-Proto 標頭。 |
如果您的應用程式在 支援的雲端平台中 執行,則 server.forward-headers-strategy 屬性預設為 NATIVE 。在所有其他情況下,它預設為 NONE 。 |
自訂 Tomcat 的 Proxy 組態
如果您使用 Tomcat,您可以額外設定用於攜帶「轉發」資訊的標頭名稱,如下列範例所示
-
屬性
-
YAML
server.tomcat.remoteip.remote-ip-header=x-your-remote-ip-header
server.tomcat.remoteip.protocol-header=x-your-protocol-header
server:
tomcat:
remoteip:
remote-ip-header: "x-your-remote-ip-header"
protocol-header: "x-your-protocol-header"
Tomcat 也配置了一個正則表達式,用於匹配要信任的內部代理。有關預設值,請參閱附錄中的 server.tomcat.remoteip.internal-proxies
條目。您可以透過在 application.properties
中新增條目來自訂閥門的配置,如下列範例所示
-
屬性
-
YAML
server.tomcat.remoteip.internal-proxies=192\.168\.\d{1,3}\.\d{1,3}
server:
tomcat:
remoteip:
internal-proxies: "192\\.168\\.\\d{1,3}\\.\\d{1,3}"
您可以將 internal-proxies 設定為空來信任所有代理(但請勿在生產環境中這樣做)。 |
您可以完全控制 Tomcat 的 RemoteIpValve
配置,方法是關閉自動配置(為此,請設定 server.forward-headers-strategy=NONE
)並使用 WebServerFactoryCustomizer
Bean 新增一個新的閥門實例。
啟用 Tomcat 的多個連接器
您可以將 org.apache.catalina.connector.Connector
新增至 TomcatServletWebServerFactory
,這可以允許多個連接器,包括 HTTP 和 HTTPS 連接器,如下列範例所示
-
Java
-
Kotlin
import org.apache.catalina.connector.Connector;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
return (tomcat) -> tomcat.addAdditionalTomcatConnectors(createConnector());
}
private Connector createConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(8081);
return connector;
}
}
import org.apache.catalina.connector.Connector
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyTomcatConfiguration {
@Bean
fun connectorCustomizer(): WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
return WebServerFactoryCustomizer { tomcat: TomcatServletWebServerFactory ->
tomcat.addAdditionalTomcatConnectors(
createConnector()
)
}
}
private fun createConnector(): Connector {
val connector = Connector("org.apache.coyote.http11.Http11NioProtocol")
connector.port = 8081
return connector
}
}
啟用 Tomcat 的 MBean 登錄
內嵌 Tomcat 的 MBean 登錄預設為停用。這可以最大限度地減少 Tomcat 的記憶體佔用量。如果您想使用 Tomcat 的 MBean,例如為了讓 Micrometer 可以使用它們來公開指標,則必須使用 server.tomcat.mbeanregistry.enabled
屬性來執行此操作,如下列範例所示
-
屬性
-
YAML
server.tomcat.mbeanregistry.enabled=true
server:
tomcat:
mbeanregistry:
enabled: true
啟用 Undertow 的多個監聽器
將 UndertowBuilderCustomizer
新增至 UndertowServletWebServerFactory
,並將監聽器新增至 Builder
,如下列範例所示
-
Java
-
Kotlin
import io.undertow.Undertow.Builder;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {
@Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
return (factory) -> factory.addBuilderCustomizers(this::addHttpListener);
}
private Builder addHttpListener(Builder builder) {
return builder.addHttpListener(8080, "0.0.0.0");
}
}
import io.undertow.Undertow
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory
import org.springframework.boot.web.server.WebServerFactoryCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyUndertowConfiguration {
@Bean
fun undertowListenerCustomizer(): WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
return WebServerFactoryCustomizer { factory: UndertowServletWebServerFactory ->
factory.addBuilderCustomizers(
UndertowBuilderCustomizer { builder: Undertow.Builder -> addHttpListener(builder) })
}
}
private fun addHttpListener(builder: Undertow.Builder): Undertow.Builder {
return builder.addHttpListener(8080, "0.0.0.0")
}
}
使用 @ServerEndpoint 建立 WebSocket 端點
如果您想在使用嵌入式容器的 Spring Boot 應用程式中使用 @ServerEndpoint
,則必須宣告單個 ServerEndpointExporter
@Bean
,如下列範例所示
-
Java
-
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.server.standard.ServerEndpointExporter
@Configuration(proxyBeanMethods = false)
class MyWebSocketConfiguration {
@Bean
fun serverEndpointExporter(): ServerEndpointExporter {
return ServerEndpointExporter()
}
}
前述範例中顯示的 Bean 會將任何 @ServerEndpoint
註釋的 Bean 註冊到基礎 WebSocket 容器。當部署到獨立 Servlet 容器時,此角色由 Servlet 容器初始化器執行,並且不需要 ServerEndpointExporter
Bean。