Spring Boot 3.2集成JSF 2.1报错:ServletRegistrationBean构造方法未定义
我为学习创建了一个Spring Boot 3.2.2项目(Java版本为17)并集成JSF,引入了如下依赖:
<dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency>
编译时出现错误:The constructor ServletRegistrationBean(FacesServlet, String) is undefined,相关代码如下:
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean public ServletRegistrationBean servletRegistrationBean() { FacesServlet servlet = new FacesServlet(); return new ServletRegistrationBean(servlet,"*.jsf"); } }
我尝试修改Spring Boot版本,但应用仍无法运行。需求是创建一个支持用户输入并在同页展示内容的xhtml页面,希望解决该报错。
1. 修正ServletRegistrationBean构造方法调用
Spring Boot 3.x中ServletRegistrationBean已移除了直接传入servlet和单个urlPattern的构造重载,需要调整写法:
@Bean public ServletRegistrationBean<FacesServlet> servletRegistrationBean() { ServletRegistrationBean<FacesServlet> registrationBean = new ServletRegistrationBean<>(new FacesServlet()); registrationBean.addUrlMappings("*.jsf"); return registrationBean; }
或者使用接收servlet和集合类型url映射的构造方法:
@Bean public ServletRegistrationBean<FacesServlet> servletRegistrationBean() { return new ServletRegistrationBean<>(new FacesServlet(), "*.jsf"); }
注意指定泛型FacesServlet,避免类型匹配问题。
2. 替换为Jakarta命名空间依赖
Spring Boot 3.x全面迁移到Jakarta EE规范,原javax命名空间的JSF、Servlet依赖会导致类冲突,需替换为Jakarta版本:
<!-- Jakarta EE版JSF API --> <dependency> <groupId>jakarta.faces</groupId> <artifactId>jakarta.faces-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!-- Jakarta Servlet API --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency>
同时代码中的导入包要同步修改:将javax.faces.webapp.FacesServlet改为jakarta.faces.webapp.FacesServlet,javax.servlet.*改为jakarta.servlet.*。
3. 补充JSF实现依赖
jakarta.faces-api仅为API定义,需引入具体实现(如Mojarra)才能运行:
<dependency> <groupId>org.glassfish</groupId> <artifactId>jakarta.faces</artifactId> <version>4.0.1</version> </dependency>
4. 添加JSF基础配置
在application.properties中配置JSF核心参数:
# JSF开发模式 server.servlet.context-param.jakarta.faces.PROJECT_STAGE=Development # 默认视图后缀 server.servlet.context-param.jakarta.faces.DEFAULT_SUFFIX=.xhtml
5. 编写示例XHTML页面与Bean
在src/main/resources/META-INF/resources下创建index.xhtml:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>JSF-Spring Boot Demo</title> </h:head> <h:body> <h:form> <h:inputText value="#{userBean.inputText}" /> <h:commandButton value="提交" action="#{userBean.submit}" /> </h:form> <h:outputText value="你输入的内容是:#{userBean.inputText}" rendered="#{not empty userBean.inputText}" /> </h:body> </html>
创建对应的视图Bean:
import jakarta.faces.view.ViewScoped; import jakarta.inject.Named; import java.io.Serializable; @Named @ViewScoped public class UserBean implements Serializable { private String inputText; public void submit() { // 提交逻辑无需额外处理,直接依赖JSF的双向绑定展示内容 } public String getInputText() { return inputText; } public void setInputText(String inputText) { this.inputText = inputText; } }
内容的提问来源于stack exchange,提问作者aneesh mathai

