You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

六、运行验证

  1. 执行Maven编译:mvn clean compile
  2. 运行Main类启动Tomcat
  3. 访问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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 18:52:56