主题
同时支持HTTP和HTTPS
可以通过配置两个嵌入式服务器实例来实现:一个用于 HTTP,另一个用于 HTTPS。然而,Spring Boot 的默认配置并不直接支持这种多端口配置。因此,你需要采取一些额外的步骤来设置。
方法 1: 使用两个 Tomcat
实例(通过自定义配置)
这种方法涉及创建两个独立的 Tomcat
容器实例,分别监听不同的端口。这可以通过编写自定义配置类来实现。
步骤
创建自定义 Tomcat 配置
编写一个配置类,为 HTTP 和 HTTPS 分别创建
TomcatServletWebServerFactory
。javaimport org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MultiPortConfig { @Bean public WebServer httpWebServer() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(8080); return factory.getWebServer(); } @Bean public WebServer httpsWebServer() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(8443) { @Override protected void postProcessContext(org.apache.catalina.Context context) { // 自定义 SSL 设置 } }; factory.addAdditionalTomcatConnectors(createSslConnector()); return factory.getWebServer(); } private Connector createSslConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("https"); connector.setSecure(true); connector.setPort(8443); // SSL 配置 Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); protocol.setSSLEnabled(true); protocol.setKeystoreFile("path/to/keystore.p12"); protocol.setKeystorePass("your_keystore_password"); protocol.setKeyAlias("myapp"); return connector; } }
这种方法的主要问题是它可能会导致应用程序启动时出现问题,因为 Spring Boot 不期望有多个
WebServer
Bean。
方法 2: 使用 server.http.port
属性(推荐)
这是更简单且推荐的方法。你可以在 application.properties
或 application.yml
中指定 HTTP 端口,并保持 HTTPS 的默认配置。
application.properties 示例
properties
# 默认 HTTPS 端口
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=your_keystore_password
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=myapp
# HTTP 端口
server.http.port=8080
application.yml 示例
yaml
server:
port: 8443
ssl:
key-store: classpath:keystore.p12
key-store-password: your_keystore_password
keyStoreType: PKCS12
keyAlias: myapp
http:
port: 8080
请注意,在某些版本的 Spring Boot 中,server.http.port
可能不起作用。如果你遇到问题,可以考虑使用下面的方法。
方法 3: 使用 Reactive
应用程序和 Netty
对于基于 Reactive
的应用程序,你可以利用 Netty 来监听多个端口。不过,这种方法适用于特定场景,不是所有项目都适用。
方法 4: 使用反向代理(如 Nginx 或 Apache)
最灵活且推荐的方式是使用反向代理服务器(如 Nginx 或 Apache),它们能够轻松地将 HTTP 请求转发到 HTTPS。
Nginx 示例配置
nginx
server {
listen 80;
server_name yourdomain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/yourdomain.crt;
ssl_certificate_key /etc/nginx/ssl/yourdomain.key;
location / {
proxy_pass http://localhost:8443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
这种方法不仅简化了应用程序的配置,还提供了更好的灵活性和安全性。例如,你可以更容易地管理证书更新、实施 HSTS 等安全策略。