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

求助:Spring Boot 3与Jakarta版JSF集成失败问题

Spring Boot 3 集成 JSF/PrimeFaces Jakarta(无CDI依赖)

核心思路

要在Spring Boot 3(Jakarta EE栈)中集成JSF/PrimeFaces且不依赖CDI,关键是让Spring接管JSF的依赖注入,同时通过配置排除CDI相关依赖、指定JSF原生工厂实现,绕过CDI探测逻辑。

步骤1:调整依赖配置

排除JSF实现包中的CDI相关依赖,避免自动引入CDI容器;同时引入PrimeFaces Jakarta版本:

<dependencies>
    <!-- Spring Boot Web Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.0.0-M4</version>
    </dependency>
    <!-- GlassFish JSF Jakarta 实现 -->
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>jakarta.faces</artifactId>
        <version>4.0.0</version>
        <exclusions>
            <!-- 排除CDI相关依赖 -->
            <exclusion>
                <groupId>jakarta.enterprise</groupId>
                <artifactId>jakarta.enterprise.cdi-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.jboss.weld.servlet</groupId>
                <artifactId>weld-servlet-shaded</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- PrimeFaces Jakarta 版本 -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>12.0.0-jakarta</version>
    </dependency>
</dependencies>

步骤2:配置JSF与Spring集成

1. 应用属性配置

在application.properties中添加以下配置,禁用CDI探测并指定JSF工厂:

# 禁用JSF的CDI自动探测
jakarta.faces.CDI_DISABLED=true
# 指定JSF生命周期工厂(绕过CDI查找)
jakarta.faces.lifecycle.LifecycleFactory=com.sun.faces.lifecycle.LifecycleFactoryImpl
# 配置JSF页面后缀
server.servlet.jsp.init-parameters.javax.faces.DEFAULT_SUFFIX=.xhtml
# 统一Servlet路径
spring.mvc.servlet.path=/

2. 注册JSF Servlet与Spring EL解析器

创建配置类,注册FacesServlet并引入Spring的EL解析器,让JSF可以访问Spring管理的Bean:

import jakarta.faces.webapp.FacesServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.jsf.el.SpringBeanFacesELResolver;

@Configuration
public class JsfIntegrationConfig {

    // 注册FacesServlet
    @Bean
    public ServletRegistrationBean<FacesServlet> facesServletRegistration() {
        ServletRegistrationBean<FacesServlet> registration = 
            new ServletRegistrationBean<>(new FacesServlet(), "*.xhtml");
        registration.setLoadOnStartup(1);
        return registration;
    }

    // 注册Spring EL解析器,让JSF能调用Spring Bean
    @Bean
    public SpringBeanFacesELResolver springBeanFacesELResolver() {
        return new SpringBeanFacesELResolver();
    }
}

步骤3:补充JSF配置文件

在src/main/resources/META-INF/下创建faces-config.xml,明确指定JSF工厂和Spring EL解析器,避免工厂查找错误:

<?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_4_0.xsd"
              version="4.0">
    <!-- 指定JSF原生工厂实现 -->
    <factory>
        <lifecycle-factory>com.sun.faces.lifecycle.LifecycleFactoryImpl</lifecycle-factory>
        <application-factory>com.sun.faces.application.ApplicationFactoryImpl</application-factory>
    </factory>
    <!-- 配置Spring EL解析器 -->
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>

步骤4:编写测试代码

1. Spring管理的Bean

创建一个Spring组件,作为JSF页面的后台Bean:

import org.springframework.stereotype.Component;
import jakarta.faces.bean.RequestScoped;

@Component
@RequestScoped
public class HelloBean {
    private String message = "Spring Boot 3 + JSF Jakarta 集成成功!";

    public String getMessage() {
        return message;
    }
}

2. JSF测试页面

在src/main/resources/templates/下创建index.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>集成测试</title>
</h:head>
<h:body>
    <h1>#{helloBean.message}</h1>
    <p:button value="PrimeFaces 组件测试" outcome="index"/>
</h:body>
</html>

内容的提问来源于stack exchange,提问作者Jan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:19:00