Spring Boot JSF 集成

2024-03-05

环境 :

雄猫8

春季启动 1.5

JSF 2.2

阿帕奇 MyFaces

春季MVC

Code :

我正在 Servlet 3.0 环境中集成 Spring Boot 和 JSF 2.2。

配置类:

JSFConfig.java - JSF 的配置。

@Configuration
@ComponentScan({"com.atul.jsf"})
public class JSFConfig {

        @Bean
        public ServletRegistrationBean servletRegistrationBean() {
            FacesServlet servlet = new FacesServlet();
            return new ServletRegistrationBean(servlet, "*.jsf");
        }

}

Spring Boot 主类:

@SpringBootApplication
@Import({ // @formatter:off 
    JPAConfig.class,
    ServiceConfig.class, // this contains UserServiceImpl.java class.
    WebConfig.class,
    JSFConfig.class,
})
public class SpringbootJpaApplication extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(SpringbootJpaApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(SpringbootJpaApplication.class);
    }
}

托管 Bean:

UserBean.java - JSF 的托管 Bean

@ManagedBean
@SessionScoped
public class UserBean implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String name;
    @ManagedProperty(value="#{userServiceImpl}")
    private UserServiceImpl userServiceImpl;

    public void addUser(){      
        System.out.println("User Gets added "+this.name);       
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public UserServiceImpl getUserServiceImpl() {
        return userServiceImpl;
    }

    public void setUserServiceImpl(UserServiceImpl userServiceImpl) {
        this.userServiceImpl = userServiceImpl;
    }
}

面片:

home.xhtml - 主页

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <title>JSF 2.0 Hello World</title>
    </h:head>
    <h:body>
        <h2>JSF 2.0 Hello World Example - hello.xhtml</h2>
        <h:form>
           <h:inputText value="#{userBean.name}"></h:inputText>
           <h:commandButton value="Submit" action="#{userBean.addUser}"></h:commandButton>
        </h:form>
    </h:body>
</html>

faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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/web-facesconfig_2_2.xsd"
              version="2.2">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
    <lifecycle>
        <phase-listener>org.springframework.web.jsf.DelegatingPhaseListenerMulticaster</phase-listener>
    </lifecycle>

</faces-config>

Issue :

1)当我提交表格时home.xhtml , userBean.addUser被叫。 2)userBean.name使用用户输入的值进行设置。 3)但是userServiceImpl一片空白。 4)这是否意味着Spring和JSF没有集成?我也注册了SpringBeanFacesELResolver如中提到的

faces-config.xml 

我还尝试从 UserBean.java 中删除所有 JSF 特定注释,并仅使用 Spring 特定注释,如下所示 -

 @Component
    @SessionScoped 
    public class UserBean implements Serializable{

        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private String name;
        @Autowired
        private UserServiceImpl userServiceImpl;


    }

但是当我提交表单时,我收到了 target Unreachable 错误#{userBean)。这意味着userBeanSpring 无法发现

5)我在这里遗漏了什么吗? 6)我没有使用Spring Boot提供的嵌入式tomcat


这就是我让 JSF 与 Spring Boot 一起工作的方式(完整Github 上的示例项目,已使用 JSF 2.3 和 Spring Boot 2 进行更新 https://github.com/xtremebiker/jsf-spring-boot):

1. 依赖关系

除了标准的 Web Starter 依赖项之外,您还需要包含标记为提供的 tomcat 嵌入式 jasper(感谢 @Fencer 在here https://stackoverflow.com/a/42155035/1199132)。否则,您将在应用程序启动时遇到异常,因为 JSF 依赖于 JSP 处理器(另请参阅我的答案末尾的第一个链接)。

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.Servlet注册

注册 JSF servlet 并将其配置为在启动时加载(不需要 web.xml)。如果使用 JSF 2.2,最好使用*.xhtml映射,至少在使用facelets时:

@Bean
public ServletRegistrationBean servletRegistrationBean() {
    ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(
            new FacesServlet(), "*.xhtml");
    servletRegistrationBean.setLoadOnStartup(1);
    return servletRegistrationBean;
}

让你的配置类实现ServletContextAware https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/ServletContextAware.html这样您就可以设置初始化参数。这里您必须强制 JSF 加载配置:

@Override
public void setServletContext(ServletContext servletContext) {
    servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration",
            Boolean.TRUE.toString());
    servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", "true");
    //More parameters...
}

3.EL集成

声明EL旋转变压器 https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/jsf/el/SpringBeanFacesELResolver.html在 faces-config.xml 中。这将成为视图文件与托管 bean 属性和方法之间的粘合剂:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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/web-facesconfig_2_2.xsd"
    version="2.2">

    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver
        </el-resolver>
    </application>

</faces-config>

4. 视图范围

编写一个自定义 Spring 作用域来模拟 JSF 视图作用域(请记住,您的 bean 将由 Spring 管理,而不是 JSF)。它应该看起来像这样:

public class ViewScope implements Scope {

    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        Map<String, Object> viewMap = FacesContext.getCurrentInstance()
            .getViewRoot().getViewMap();
        if (viewMap.containsKey(name)) {
            return viewMap.get(name);
        } else {
            Object object = objectFactory.getObject();
            viewMap.put(name, object);
            return object;
        }
    }

    @Override
    public String getConversationId() {
        return null;
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {

    }

    @Override
    public Object remove(String name) {
        return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
    }

    @Override
    public Object resolveContextualObject(String arg0) {
        return null;
    }

}

并将其注册到您的配置类中:

@Bean
public static CustomScopeConfigurer viewScope() {
    CustomScopeConfigurer configurer = new CustomScopeConfigurer();
    configurer.setScopes(
            new ImmutableMap.Builder<String, Object>().put("view", new ViewScope()).build());
    return configurer;
}

5. 准备出发!

现在您可以通过以下方式声明您的托管 bean。记得使用@Autowired(最好在构造函数中)而不是@ManagedProperty,因为您正在处理 Spring Bean。

@Component
@Scope("view")
public class MyBean {

    //Ready to go!

}

仍有待实现

我无法在 Spring Boot 上下文中使用 JSF 特定注释。所以@FacesValidator, @FacesConverter, @FacesComponent、等等不能使用。尽管如此,还是有机会在 faces-config.xml 中声明它们(请参阅xsd http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd),还是老办法。


也可以看看:

  • Spring Boot 与 JSF;找不到工厂 javax.faces.context.FacesContextFactory 的备份 https://stackoverflow.com/questions/25479986/spring-boot-with-jsf-could-not-find-backup-for-factory-javax-faces-context-face/25509937#25509937
  • 将 JSF 2.0 的 ViewScope 移植到 Spring 3.0 https://www.primefaces.org/port-jsf-2-0s-viewscope-to-spring-3-0/
  • JSP 文件未在 Spring Boot Web 应用程序中呈现 https://stackoverflow.com/questions/20602010/jsp-file-not-rendering-in-spring-boot-web-application
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot JSF 集成 的相关文章

随机推荐

  • 有没有办法向管理员用户显示 Django 调试堆栈跟踪页面,即使设置中 DEBUG=False 也是如此?

    场景 我宁愿非技术同事直接通过电子邮件向我发送错误 而不是通过 SSH 进入盒子来检索堆栈跟踪 Django 有没有办法或钩子来做这样的事情 例如 def 500 error happened request psuedocode gt l
  • 如何使用 pd.Grouper 按月对日期进行分组?

    我搜索了 stackoverflow 以了解如何按月对 DateTime 进行分组 由于某种原因 即使在我传递数据帧之后 我仍然收到此错误pd to datetime 类型错误 仅对 DatetimeIndex TimedeltaIndex
  • Django 会话过期?

    从 django 的文档中 我的印象是调用 request session set expiry 300 从一种观点来看 会导致会话在五分钟后过期不活动 但是 这不是我在 django trunk 中遇到的行为 如果我从一个视图调用此方法
  • 如何配置 ckeditor 不将内容换行到

    块中?

    我在用ckeditor http ckeditor com 在我的网站上 让用户更容易输入 HTML 但是 我从 ckeditor 返回的数据包含在 p p 块 这是我不想要的 是否有一些配置设置强制编辑器不将文本换行 将以下内容添加到您的
  • GridLayout(不是GridView)如何均匀拉伸所有子项

    我想要一个 2x2 的网格 里面有一个按钮 这只是 ICS 所以我尝试使用给出的新 GridLayout 这是我的布局的 XML
  • 从 RxJS Observable 中过滤未定义的内容

    是否有特定的习惯用法或实用程序用于过滤undefined从 RxJS 可观察到的 这段代码具有我想要的行为 obs pipe filter x gt x undefined 一些替代方案是 obs pipe filter x gt x fo
  • 脚本的布尔参数

    在 Python 中 我了解如何将 int 和 str 参数添加到脚本中 parser argparse ArgumentParser description Mydescription parser add argument l type
  • Elasticsearch - 每个文档的匹配数

    我使用此查询来搜索字段中出现的短语 query match phrase content my test phrase 我需要计算每个文档的每个短语发生了多少次匹配 如果这可能的话 我考虑过聚合器 但认为它们不满足要求 因为它们会给我整个索
  • 如何在 Nextjs 中切换类并更改 CSS?

    我正在开发一个 Next js 项目 其中菜单打开时显示 p 切换菜单类 我设法做到了这一点 但是当我在 CSS 中添加该类时 它没有考虑这两个类 这是我的代码 成分 import useState from react import st
  • 将不完整的嵌套列表放入矩形 ndarray 中

    在Python 也使用numpy 中 我有一个列表列表的列表 每个列表的长度不同 header1 header2 item1 value1 header1 header2 header3 item2 value2 item3 value3
  • Haskell:最简单的 wai 示例的问题

    我是 Haskell 新手 我正在尝试让 wai 包正常工作 因为我对使用 Haskell 进行 Web 应用程序感兴趣 我尝试从第一个 最简单的例子开始wai http github com snoyberg wai主页 1 LANGUA
  • SQL Server 字符串执行带有输出参数的过程

    如何将输出参数与 String Exec 一起使用 考虑使用 标准 语法进行以下查询 DECLARE testString nvarchar 50 EXEC testProcedure param1 testString OUTPUT SE
  • MSVSP100D.dll 缺少在窗口 8 中与 opencv 2.4.1 配合使用 [已关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有以下场景 我正在尝试在 Wind
  • 使用 Cargo 时如何获得带有调试信息的发布版本?

    以下命令 cargo build 产生一个未优化 build with调试信息 相反 cargo build release 产生一个优化 build without调试信息 有没有一种方法可以产生优化 build with调试信息 我需要
  • Heroku 上的 Radiant 扩展?

    有人有过将 Radiant CMS 扩展实际应用到 Heroku 实例上的经验吗 我尝试删除子模块并将文件添加回来 但运气不太好 Heroku 目前不支持 git 子模块 然而 他们的 优秀的 文档表达了解决这个问题的方法 在这里查看 ht
  • 删除 .svn/pristine 的内容是否安全?

    我正在使用一个大型应用程序 我从我的存储库中签出了该应用程序的大部分内容 svn pristine文件夹 据我了解 原始文件夹包含我的workingCopy目录中的文件副本 话虽如此 删除这些文件可以吗 我真的需要它们吗 我已经备份了文件
  • 如何在 C# 中修改装箱值而不创建新对象?

    如何在 C 中修改装箱值而不创建新对象 例如 如果我有object o 5 我想改变盒装的值5 to 6 我怎样才能做到这一点 The o 6 将在堆上创建一个新对象并将对该对象的引用分配给o 还有其他方法可以更改盒装值吗 你可以自己 拳击
  • 从 ansible 运行 powershell 脚本并注册输出

    我正在尝试运行一个 Powershell 脚本 该脚本在远程 Windows PC 上使用 ansible 从 MSI 文件读取 ProductGUID powershell 在本地工作台上作为 ps1 文件运行 但从 ansible 中它
  • 请求超时并显示代码

    Error Domain NSURLErrorDomain Code 1001 The request timed out UserInfo NSUnderlyingError 0x608000244a70 Error Domain kCF
  • Spring Boot JSF 集成

    环境 雄猫8 春季启动 1 5 JSF 2 2 阿帕奇 MyFaces 春季MVC Code 我正在 Servlet 3 0 环境中集成 Spring Boot 和 JSF 2 2 配置类 JSFConfig java JSF 的配置 Co