为 Feat 服务启用 HTTPS
This content is not available in your language yet.
如果你的服务要进入真实网络环境,HTTPS 通常不是可选项。
这篇文档不讨论完整的 TLS 理论,而是回答更直接的问题:在 Feat 里,怎样把一个已经能工作的 HTTP 服务切到 HTTPS。
最常见的使用场景
Section titled “最常见的使用场景”- 本地开发时模拟 HTTPS 环境
- 内网环境里直接跑 HTTPS 服务
- 对外暴露服务前,先把证书和启动方式跑通
第一步:准备证书
Section titled “第一步:准备证书”本地开发最省事的方式是用 mkcert 生成一组本地可信证书。
mkcert example.com "*.example.com" example.test localhost 127.0.0.1 ::1命令执行成功后,你会得到一对 PEM 文件,类似:
example.com+5.pemexample.com+5-key.pem
把它们放进项目的 src/main/resources 目录,或者任何你能稳定读取到的资源路径里。
第二步:把 HTTP 服务切到 HTTPS
Section titled “第二步:把 HTTP 服务切到 HTTPS”Feat 本身不需要你重写一套服务逻辑。
你真正需要做的是:在原来的 HTTP 服务上加一个 SslPlugin。
import org.smartboot.socket.extension.plugins.SslPlugin;import org.smartboot.socket.extension.ssl.factory.PemServerSSLContextFactory;import tech.smartboot.feat.Feat;
import java.io.InputStream;
public class HttpsPemDemo { public static void main(String[] args) throws Exception { InputStream certPem = HttpsPemDemo.class.getClassLoader().getResourceAsStream("example.org.pem"); InputStream keyPem = HttpsPemDemo.class.getClassLoader().getResourceAsStream("example.org-key.pem");
SslPlugin sslPlugin = new SslPlugin(new PemServerSSLContextFactory(certPem, keyPem));
Feat.httpServer(opt -> opt.addPlugin(sslPlugin)) .httpHandler(req -> req.getResponse().write("Hello Feat Https")) .listen(); }}这里真正发生的事情只有一件:
- 你的 Feat 服务仍然是同一个服务
- 只是监听链路前面多了一个 SSL/TLS 插件
第三步:验证 HTTPS 是否真的生效
Section titled “第三步:验证 HTTPS 是否真的生效”启动程序后,直接访问:
https://localhost:8080
如果浏览器能够正常打开,并看到类似页面,说明 HTTPS 已经真正工作起来了:

有关实际示例代码,可直接参考:
什么时候需要关心 SSLEngine
Section titled “什么时候需要关心 SSLEngine”大多数业务代码根本不需要直接碰 SSLEngine。
只有在你确实需要读取底层 TLS 连接信息时,才值得继续处理。
默认情况下,业务层直接调用 req.getSslEngine(),很可能拿到的是 null。
原因很简单:SSLEngine 是底层通信层创建的,应用层默认感知不到。
如果你明确需要它,就要在 SslPlugin 初始化时把它传上来:
import org.smartboot.socket.extension.plugins.SslPlugin;import org.smartboot.socket.extension.ssl.factory.AutoServerSSLContextFactory;import tech.smartboot.feat.Feat;import tech.smartboot.feat.core.server.HttpRequest;
import javax.net.ssl.SSLEngine;import java.util.function.Consumer;
public class HttpsSSLEngineDemo { public static void main(String[] args) throws Exception { SslPlugin sslPlugin = new SslPlugin(new AutoServerSSLContextFactory(), (Consumer<SSLEngine>) sslEngine -> { HttpRequest.SSL_ENGINE_THREAD_LOCAL.set(sslEngine); });
Feat.httpServer(opt -> opt.addPlugin(sslPlugin)) .httpHandler(req -> { SSLEngine engine = req.getSslEngine(); if (engine == null) { req.getResponse().write("engine is null"); } else { req.getResponse().write("engine=" + engine); } }).listen(); }}这不是 HTTPS 启动的必备步骤,而是“你需要拿 TLS 上下文时”的扩展做法。
生产环境应该怎么理解这件事
Section titled “生产环境应该怎么理解这件事”本地开发时,你的目标只是先把 HTTPS 跑通。
到了生产环境,真正需要关注的是:
- 证书由谁签发、谁轮换
- 证书文件如何注入容器或主机
- 是否由反向代理统一终止 TLS
- 服务本身是否真的需要直接持有证书
换句话说,这篇文档解决的是“Feat 这层怎么启 HTTPS”,不是替代完整的运维安全方案。
浏览器提示证书不受信任
Section titled “浏览器提示证书不受信任”如果你用的是自签名证书,这是正常现象。
在本地开发环境里,优先使用 mkcert 这类工具来减少这类问题。
证书文件加载不到
Section titled “证书文件加载不到”优先检查:
- 文件名是否和代码里完全一致
- 资源是否真的打进了
resources getResourceAsStream(...)返回值是否为null
已经加了 SslPlugin,但还是按 HTTP 访问
Section titled “已经加了 SslPlugin,但还是按 HTTP 访问”确认你访问的是 https://,而不是 http://。
TLS 已启用不代表服务会自动帮你把 HTTP 重定向到 HTTPS。
我是不是应该一开始就研究 SSLEngine
Section titled “我是不是应该一开始就研究 SSLEngine”不用。
除非你已经明确要做更底层的 TLS 处理,否则先把 HTTPS 跑通就够了。
- ServerOptions 配置指南:把 HTTPS 和端口、调试、代理协议放在一起理解
- 打包与部署:如果你下一步准备把服务放进容器或交付到环境里