如何在JSF 3.0项目中嵌入Tomcat 10.1.5并通过Main类启动
基于JSF 3.0、Java 17、CDI 2.0的嵌入式Tomcat 10.1.5项目实现方案
一、Maven依赖配置
在pom.xml中添加以下适配Jakarta EE 9+的依赖(Tomcat 10.x基于Jakarta EE规范):
<dependencies> <!-- 嵌入式Tomcat核心组件 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>10.1.5</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>10.1.5</version> </dependency> <!-- JSF 3.0 实现(Mojarra) --> <dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>3.0.1</version> </dependency> <!-- CDI 2.0 实现(Weld Servlet版) --> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>4.0.3.Final</version> </dependency> <!-- Jakarta Servlet API(仅编译时依赖) --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>5.0.0</version> <scope>provided</scope> </dependency> </dependencies>
二、标准项目结构
保持Web项目的经典目录结构:
src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── Main.java # 嵌入式Tomcat启动入口 │ │ └── bean/ │ │ └── HelloBean.java # CDI托管Bean │ ├── resources/ │ │ └── META-INF/ │ │ └── beans.xml # CDI启用标记文件 │ └── webapp/ │ ├── index.xhtml # JSF测试页面 │ └── WEB-INF/ │ └── faces-config.xml # JSF版本声明文件 └── pom.xml
三、嵌入式Tomcat启动类(Main.java)
手动配置Tomcat容器,注册CDI监听器与JSF Servlet:
package com.example; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; import org.apache.catalina.startup.Tomcat; import jakarta.servlet.ServletRegistration; import java.io.File; public class Main { public static void main(String[] args) throws LifecycleException { // 初始化Tomcat实例,设置端口 Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); // 绑定Web应用根目录 String webappDir = "src/main/webapp/"; Context context = tomcat.addWebapp("/", new File(webappDir).getAbsolutePath()); // 配置类路径资源,确保Tomcat能加载编译后的Bean String classOutputDir = "target/classes"; context.getResources().createWebResourceSet( org.apache.catalina.webresources.StandardRoot.RESOURCE_WEB_INF_CLASSES, "/WEB-INF/classes", new File(classOutputDir).getAbsolutePath(), "/" ); // 注册CDI Weld监听器,启动CDI容器 context.addApplicationListener("org.jboss.weld.environment.servlet.Listener"); // 注册JSF FacesServlet,设置启动优先级与映射规则 ServletRegistration.Dynamic facesServlet = context.addServlet("FacesServlet", "jakarta.faces.webapp.FacesServlet"); facesServlet.setLoadOnStartup(1); facesServlet.addMapping("*.xhtml"); // 启动Tomcat并阻塞等待请求 tomcat.start(); tomcat.getServer().await(); } }
四、核心配置文件
1. META-INF/beans.xml
空文件即可启用CDI 2.0扫描:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="all"> </beans>
2. WEB-INF/faces-config.xml
声明JSF 3.0版本:
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_3_0.xsd" version="3.0"> </faces-config>
五、CDI Bean与JSF测试页面
1. CDI托管Bean(HelloBean.java)
package com.example.bean; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; @Named @RequestScoped public class HelloBean { private String message = "JSF 3.0 + CDI 2.0 + 嵌入式Tomcat"; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
2. JSF测试页面(index.xhtml)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <head> <title>嵌入式Tomcat JSF Demo</title> </head> <body> <h1>#{helloBean.message}</h1> <h:form> <h:inputText value="#{helloBean.message}" /> <h:commandButton value="更新内容" action="#{helloBean.getMessage}" /> </h:form> </body> </html>
六、运行验证
- 执行Maven编译:
mvn clean compile - 运行
Main类启动Tomcat - 访问
http://localhost:8080/index.xhtml,页面应正常显示CDI Bean内容,输入框修改后点击按钮可实时更新
关键注意事项
- Tomcat 10.x完全使用
jakarta.*命名空间,所有API依赖必须对应Jakarta版本,不可混用旧javax.*包 - Weld Servlet Shaded包已包含CDI核心组件,无需额外添加Weld核心依赖
- 必须手动配置类路径资源集,否则Tomcat无法加载编译后的Java类
- JSF Servlet映射需设置为
*.xhtml,确保JSF容器能拦截并处理页面请求
内容的提问来源于stack exchange,提问作者Johan Silva
相关产品推荐
相关产品推荐

