嵌入式Jetty多WebAppContext部署404问题排查求助
同一Jetty实例部署多WebAppContext到不同连接器的解决方案
当然可以在同一个Jetty实例中部署多个WebAppContext,而且完全能实现分别绑定到HTTP、HTTPS不同连接器的需求!你的思路方向是对的,出现404大概率是虚拟主机配置或者连接器-上下文绑定的环节出了问题,咱们一步步拆解排查:
可能的问题点
- 虚拟主机配置不匹配:你给WebAppContext设置了虚拟主机,但没给对应的连接器绑定相同的虚拟主机标识,导致连接器无法把请求路由到对应的上下文。
- 上下文路径与访问路径不一致:比如你把WebAppContext的
contextPath设成了/,但访问时用了/hello1,自然会404。 - Handler管理不当:多个WebAppContext需要用
HandlerCollection或ContextHandlerCollection来统一管理,直接添加可能导致上下文没被正确注册。
正确的实现代码示例
下面是完整的可运行代码框架,你可以对照自己的代码调整:
1. 创建Jetty服务器与连接器
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; public class MultiWarJetty { public static void main(String[] args) throws Exception { Server server = new Server(); // --- HTTP连接器配置 --- ServerConnector httpConnector = new ServerConnector(server); httpConnector.setPort(18081); // 给HTTP连接器绑定虚拟主机标识"http-only" httpConnector.setVirtualHosts(new String[]{"http-only"}); // --- HTTPS连接器配置(请替换成你的SSL证书信息)--- SslContextFactory.Server sslFactory = new SslContextFactory.Server(); sslFactory.setKeyStorePath("/your/path/to/keystore.jks"); sslFactory.setKeyStorePassword("your-keystore-password"); sslFactory.setKeyManagerPassword("your-key-password"); ServerConnector httpsConnector = new ServerConnector(server, sslFactory); httpsConnector.setPort(18080); // 给HTTPS连接器绑定虚拟主机标识"https-only" httpsConnector.setVirtualHosts(new String[]{"https-only"}); // 将两个连接器添加到服务器 server.setConnectors(new ServerConnector[]{httpConnector, httpsConnector});
2. 配置并绑定WebAppContext到对应连接器
// --- 第一个WAR:绑定到HTTPS连接器 --- WebAppContext hello1Context = new WebAppContext(); hello1Context.setContextPath("/hello1"); // 访问路径前缀 hello1Context.setWar("webapps/hello1.war"); // WAR包路径(确保路径正确) // 指定该上下文仅响应"https-only"虚拟主机的请求 hello1Context.setVirtualHosts(new String[]{"https-only"}); // --- 第二个WAR:绑定到HTTP连接器 --- WebAppContext hello2Context = new WebAppContext(); hello2Context.setContextPath("/hello2"); hello2Context.setWar("webapps/hello2.war"); // 指定该上下文仅响应"http-only"虚拟主机的请求 hello2Context.setVirtualHosts(new String[]{"http-only"});
3. 注册Handler并启动服务器
// 用HandlerCollection管理多个WebAppContext HandlerCollection handlerCollection = new HandlerCollection(); handlerCollection.setHandlers(new WebAppContext[]{hello1Context, hello2Context}); server.setHandler(handlerCollection); // 启动服务器 server.start(); server.join(); } }
额外排查建议
- 检查WAR包路径:确保
setWar的路径是正确的,建议使用绝对路径(比如/opt/jetty/webapps/hello1.war)避免相对路径带来的歧义。 - 查看Jetty日志:启动时日志会显示每个WebAppContext的加载状态,比如
Deploying web application archive xxx.war,如果没看到这条日志,说明WAR包没被正确加载。 - 验证虚拟主机绑定:日志中会输出连接器和上下文的虚拟主机配置,确认两者的标识完全一致(大小写敏感)。
内容的提问来源于stack exchange,提问作者webbed
相关产品推荐
相关产品推荐

