嵌入式 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 示例展示了如何为 Spring MVC 排除 Tomcat 并包含 Jetty:
<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")
}
}
}
注意:spring-boot-starter-reactor-netty
是使用 WebClient
类所必需的,因此即使你需要包含不同的 HTTP 服务器,也可能需要保留对 Netty 的依赖。
禁用 Web 服务器
如果你的类路径包含启动 Web 服务器所需的组件,Spring Boot 将自动启动它。
要禁用此行为,请在 application.properties
中配置 WebApplicationType
,如下例所示:
-
Properties
-
YAML
spring.main.web-application-type=none
spring:
main:
web-application-type: "none"
更改 HTTP 端口
在独立应用程序中,主 HTTP 端口默认为 8080
,但可以使用 server.port
设置(例如,在 application.properties
中或作为系统属性)。
由于 Environment
值的宽松绑定,你也可以使用 SERVER_PORT
(例如,作为操作系统环境变量)。
要完全关闭 HTTP 端点但仍创建 WebApplicationContext
,请使用 server.port=-1
(这样做有时对测试很有用)。
有关更多详细信息,请参阅"Spring Boot 特性"部分中的 自定义嵌入式 Servlet 容器,或 ServerProperties
类。
在运行时发现 HTTP 端口
你可以从日志输出或通过 WebServerApplicationContext
的 WebServer
访问服务器运行的端口。
获取该端口并确保它已初始化的最佳方法是添加类型为 ApplicationListener<WebServerInitializedEvent>
的 @Bean
,并在事件发布时从事件中提取容器。
使用 @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
的测试也可以通过使用 @LocalServerPort
注解将实际端口注入到字段中,如下例所示:
-
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
中启用它,如下所示:
-
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 属性:
-
Properties
-
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"
使用上述示例的配置意味着应用程序不再支持端口 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 属性:
-
Properties
-
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 包
或者,SSL 信任材料可以在 SSL 包中配置,并应用于 Web 服务器,如下例所示:
-
Properties
-
YAML
server.port=8443
server.ssl.bundle=example
server:
port: 8443
ssl:
bundle: "example"
使用包时, |
配置服务器名称指示
Tomcat、Netty 和 Undertow 可以配置为对各个主机名使用唯一的 SSL 信任材料,以支持服务器名称指示(SNI)。 Jetty 不支持 SNI 配置,但如果向 Jetty 提供多个证书,它可以 自动设置 SNI。
假设已配置了名为 web
、web-alt1
和 web-alt2
的 SSL 包,以下配置可用于将每个包分配给嵌入式 Web 服务器提供的主机名:
-
Properties
-
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
指定的包将用于默认主机,以及任何不支持 SNI 的客户端。
如果配置了任何 server.ssl.server-name-bundles
,则必须配置此默认包。
配置 HTTP/2
你可以使用 server.http2.enabled
配置属性在 Spring Boot 应用程序中启用 HTTP/2 支持。
同时支持 h2
(基于 TLS 的 HTTP/2)和 h2c
(基于 TCP 的 HTTP/2)。
要使用 h2
,还必须启用 SSL。
当未启用 SSL 时,将使用 h2c
。
例如,当你的应用程序 在代理服务器后面运行时,你可能想要使用 h2c
,该代理服务器正在执行 TLS 终止。
使用 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
。
你可以声明这样的组件并访问与你的选择相关的服务器工厂:你应该为所选服务器(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 提供的那个。
当你这样做时,自动配置的自定义器仍然会应用于你的自定义工厂,所以要谨慎使用该选项。
向应用程序添加 Servlet、Filter 或 Listener
在 servlet 栈应用程序中,即使用 spring-boot-starter-web
的应用程序,有两种方法可以向应用程序添加 Servlet
、Filter
、ServletContextListener
以及 Servlet API 支持的其他监听器:
使用 Spring Bean 添加 Servlet、Filter 或 Listener
要使用 Spring bean 添加 Servlet
、Filter
或 servlet *Listener
,你必须为其提供 @Bean
定义。
当你想要注入配置或依赖项时,这非常有用。
但是,你必须非常小心,不要导致太多其他 bean 的急切初始化,因为它们必须在应用程序生命周期的早期安装在容器中。
(例如,让它们依赖于你的 DataSource
或 JPA 配置不是一个好主意。)
你可以通过在首次使用时延迟初始化 bean 而不是在初始化时初始化来解决这些限制。
对于过滤器和 servlet,你还可以通过添加 FilterRegistrationBean
或 ServletRegistrationBean
来添加映射和初始化参数,而不是或除了底层组件之外。
如果在过滤器注册上未指定 |
像任何其他 Spring bean 一样,你可以定义 servlet 过滤器 bean 的顺序;请确保查看 将 Servlets、Filters 和 Listeners 注册为 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
}
}
使用类路径扫描添加 Servlet、Filter 和 Listener
通过使用 @ServletComponentScan
注解 @Configuration
类并指定包含要注册的组件的包,可以自动将 @WebServlet
、@WebFilter
和 @WebListener
注解的类注册到嵌入式 servlet 容器中。
默认情况下,@ServletComponentScan
从带注解的类的包开始扫描。
配置访问日志
可以通过各自的命名空间为 Tomcat、Undertow 和 Jetty 配置访问日志。
例如,以下设置使用 自定义模式在 Tomcat 上记录访问。
-
Properties
-
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 的访问日志,如下例所示:
-
Properties
-
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 的访问日志:
-
Properties
-
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 文档。
在代理服务器后面运行
如果你的应用程序在代理、负载均衡器或云中运行,请求信息(如主机、端口、方案等)可能会在传输过程中发生变化。
你的应用程序可能在 10.10.10.10:8080
上运行,但 HTTP 客户端应该只看到 example.org
。
RFC7239 "Forwarded Headers" 定义了 Forwarded
HTTP 头;代理可以使用此头提供有关原始请求的信息。
你可以配置应用程序读取这些头,并在创建链接并将其发送给 HTTP 302 响应、JSON 文档或 HTML 页面中的客户端时自动使用该信息。
还有一些非标准头,如 X-Forwarded-Host
、X-Forwarded-Port
、X-Forwarded-Proto
、X-Forwarded-Ssl
和 X-Forwarded-Prefix
。
如果代理添加了常用的 X-Forwarded-For
和 X-Forwarded-Proto
头,将 server.forward-headers-strategy
设置为 NATIVE
就足以支持这些。
使用此选项,Web 服务器本身原生支持此功能;你可以查看其特定文档以了解具体行为。
如果这还不够,Spring Framework 为 servlet 栈提供了 ForwardedHeaderFilter,为响应式栈提供了 ForwardedHeaderTransformer。
你可以通过将 server.forward-headers-strategy
设置为 FRAMEWORK
在应用程序中使用它们。
提示:如果你使用 Tomcat 并在代理处终止 SSL,应该将 server.tomcat.redirect-context-root
设置为 false
。
这允许在执行任何重定向之前遵守 X-Forwarded-Proto
头。
注意:如果你的应用程序在 支持的云平台中运行,server.forward-headers-strategy
属性默认为 NATIVE
。
在所有其他情况下,它默认为 NONE
。
自定义 Tomcat 的代理配置
如果你使用 Tomcat,你还可以配置用于携带"forwarded"信息的头的名称,如下例所示:
-
Properties
-
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
添加条目来自定义阀的配置,如下例所示:
-
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
设置为空来信任所有代理(但在生产环境中不要这样做)。
你可以通过关闭自动配置(为此,设置 server.forward-headers-strategy=NONE
)并使用 WebServerFactoryCustomizer
bean 添加新的阀实例来完全控制 Tomcat 的 RemoteIpValve
的配置。
在 Tomcat 中启用多个连接器
你可以向 TomcatServletWebServerFactory
添加 Connector
,这可以允许多个连接器,包括 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
属性来执行此操作,如下例所示:
-
Properties
-
YAML
server.tomcat.mbeanregistry.enabled=true
server:
tomcat:
mbeanregistry:
enabled: true
在 Undertow 中启用多个监听器
向 UndertowServletWebServerFactory
添加 UndertowBuilderCustomizer
,并向 io.undertow.Undertow.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。