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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 10:42:44