求助: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
相关产品推荐
相关产品推荐

