JavaServer Faces (JSF) with Spring

Last modified: April 30, 2018

 

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this article we will look at a recipe for accessing beans defined in Spring from within a JSF managed bean and a JSF page, for the purposes of delegating the execution of business logic to the Spring beans.

This article presumes the reader has a prior understanding of both JSF and Spring separately. The article is based on the Mojarra implementation of JSF.

2. In Spring

Let’s have the following bean defined in Spring. The UserManagementDAO bean adds a username to an in-memory store, and it’s defined by the following interface:

1
2
3
public interface UserManagementDAO {
    boolean createUser(String newUserData);
}

The implementation of the bean is configured using the following Java config:

1
2
3
4
5
6
public class SpringCoreConfig {
    @Bean
    public UserManagementDAO userManagementDAO() {
        return new UserManagementDAOImpl();
    }
}

Or using the following XML configuration:

1
2
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean class="com.baeldung.dao.UserManagementDAOImpl" id="userManagementDAO"/>

We define the bean in XML, and register CommonAnnotationBeanPostProcessor to ensure that the @PostConstruct annotation is picked up.

3. Configuration

The following sections explain the configuration items that enable the integration of the Spring and JSF contexts.

3.1. Java Configuration Without web.xml

By implementing the WebApplicationInitializer we are able to programatically configure the ServletContext. The following is the onStartup() implementation inside the MainWebAppInitializer class:

1
2
3
4
5
public void onStartup(ServletContext sc) throws ServletException {
    AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
    root.register(SpringCoreConfig.class);
    sc.addListener(new ContextLoaderListener(root));
}

The AnnotationConfigWebApplicationContext bootstraps the Spring’g context and adds the beans by registering the SpringCoreConfig class.

Similarly, in the Mojarra implementation there is a FacesInitializer class that configures the FacesServlet. To use this configuration it is enough to extend the FacesInitializer. The complete implementation of the MainWebAppInitializer, is now as follows:

1
2
3
4
5
6
7
public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext sc) throws ServletException {
        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(SpringCoreConfig.class);
        sc.addListener(new ContextLoaderListener(root));
    }
}

3.2. With web.xml

We’ll start by configuring the ContextLoaderListener in web.xml file of the application:

1
2
3
4
5
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

This listener is responsible for starting up the Spring application context when the web application starts up. This listener will look for a spring configuration file named applicationContext.xml by default.

3.3. faces-config.xml

We now configure the SpringBeanFacesELResolver in the face-config.xml file:

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

An EL resolver is a pluggable component supported by the JSF framework, allowing us to customize the behavior of the JSF runtime when evaluating Expression Language (EL) expressions. This EL resolver will allow the JSF runtime access Spring components via EL expressions defined in JSF.

4. Accessing Spring Beans in JSF

At this point, our JSF web application is primed to access our Spring bean from either a JSF backing bean, or from a JSF page.

4.1. From a Backing Bean JSF 2.0

The Spring bean can now be accessed from a JSF backing bean. Depending on the version of JSF you’re running, there are two possible methods. With JSF 2.0, you use the @ManagedProperty annotation on the JSF managed bean.

1
2
3
4
5
6
7
@ManagedBean(name = "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @ManagedProperty(value = "#{userManagementDAO}")
    transient private IUserManagementDAO theUserDao;
 
    private String userName;
1
2
    // getters and setters
}

Note that the getter and setter are mandatory when using the @ManagedProperty. 
Now – to assert the accessibility of a Spring bean from a managed bean, we will add the createNewUser() method:

1
2
3
4
5
6
7
8
public void createNewUser() {
    FacesContext context = FacesContext.getCurrentInstance();
    boolean operationStatus = userDao.createUser(userName);
    context.isValidationFailed();
    if (operationStatus) {
        operationMessage = "User " + userName + " created";
    }
}

The gist of the method is using the userDao Spring bean, and accessing its functionality.

4.2. From a Backing Bean in JSF 2.2

Another approach, valid only in JSF2.2 and above, is to use CDI’s @Inject annotation. This is applicable to JSF managed beans (with the @ManagedBean annotation), and CDI-managed beans (with the @Named annotation).

Indeed, with a CDI annotation, this is the only valid method of injecting the bean:

1
2
3
4
5
6
@Named( "registration")
@RequestScoped
public class RegistrationBean implements Serializable {
    @Inject
    UserManagementDAO theUserDao;
}

With this approach, the getter and setter are not necessary. Also note that the EL expression is absent.

4.3. From a JSF View

The createNewUser() method will be triggered from the following JSF page:

1
2
3
4
5
6
7
8
9
10
11
<h:form>
    <h:panelGrid id="theGrid" columns="3">
        <h:outputText value="Username"/>
        <h:inputText id="firstName" binding="#{userName}" required="true"
          requiredMessage="#{msg['message.valueRequired']}" value="#{registration.userName}"/>
        <h:message for="firstName" style="color:red;"/>
        <h:commandButton value="#{msg['label.saveButton']}" action="#{registration.createNewUser}"
          process="@this"/>
        <h:outputText value="#{registration.operationMessage}" style="color:green;"/>
    </h:panelGrid>
</h:form>

To render the page, start the server and navigate to:

1
http://localhost:8080/jsf/index.jsf

We can also use EL in the JSF view, to access the Spring bean. To test it it is enough to change the line number 7 from the previously introduced JSF page to:

1
2
<h:commandButton value="Save"
  action="#{registration.userDao.createUser(userName.value)}"/>

Here, we call the createUser method directly on the Spring DAO, passing the bind value of the userName to the method from within the JSF page, circumventing the managed bean all together.

5. Conclusion

We examined a basic integration between the Spring and JSF contexts, where we’re able to access a Spring bean in a JSF bean and page.

It’s worth noting that while the JSF runtime provides the pluggable architecture that enables the Spring framework to provide integration components, the annotations from the Spring framework cannot be used in a JSF context and vice versa.

What this means is that you’ll not be able to use annotations like @Autowired or @Component etc. in a JSF managed bean, or use the @ManagedBean annotation on a Spring managed bean. You can however, use the @Inject annotation in both a JSF 2.2+ managed bean, and a Spring bean (because Spring supports JSR-330).

The source code that accompanies this article is available at GitHub.

JavaServer Faces (JSF) with Spring的更多相关文章

  1. JSF(JavaServer Faces)简介

    JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准).它提供了一种以组件为中心的 ...

  2. 使用JavaServer Faces技术的Web模块:hello1 example

    该hello1应用程序是一个Web模块,它使用JavaServer Faces技术来显示问候语和响应.您可以使用文本编辑器查看应用程序文件,也可以使用NetBeans IDE. 此应用程序的源代码位于 ...

  3. JavaServer Faces 2.0 can not be installed解决方案

    问题描述:maven项目出现如下错误 JavaServer Faces 2.0 requires Dynamic Web Module 2.5 or newer..Maven Java EE Conf ...

  4. JavaServer Faces 2.2 requires Dynamic Web Module 2.5 or newer

    Description Resource Path Location Type JavaServer Faces 2.2 can not be installed : One or more cons ...

  5. JavaServer Faces生命周期概述

    JavaServer Faces应用程序的生命周期在客户端为页面发出HTTP请求时开始,并在服务器响应该页面并转换为HTML时结束. 生命周期可以分为两个主要阶段:执行和渲染.执行阶段进一步分为子阶段 ...

  6. 比较JSF、Spring MVC、Stripes、Struts 2、Tapestry、Wicket

    2009-06-23 Java Web层框架--JSF.Spring MVC.Stripes.Struts 2.Tapestry和Wicket他们各自的优点和缺点: JSF 优点: ◆Java EE标 ...

  7. 解决JavaServer Faces 2.2 requires Dynamic Web Module 2.5 or newer问题

    ** 错误1: **在eclipse中新创建一个web项目的时候项目下的JSP文件中会爆出错误:The superclass “javax.servlet.http.HttpServlet” was ...

  8. jsf使用spring注入的bean

    jsf的后台bean中使用spring定义的service,需要使用@ManagedProperty,并且要具有该属性的getter/setter方法. package cn.catr.lm.idc. ...

  9. JSF结合Spring 引入ViewScope

    当JSF项目的faceConfig中配置了Spring的配置代码 <application> <el-resolver>org.springframework.web.jsf. ...

随机推荐

  1. C# Note30: 软件加密机制以及如何防止反编译

    参考文章: C#软件license管理(简单软件注册机制) 软件加密技术和注册机制 .NET中的许可证机制--License 背景 .net是一种建立在虚拟机上执行的语言,它直接生成 MSIL 的中间 ...

  2. 版本控制--git+idea

  3. python之路--初识面向对象

    一 . 初识面向对象 面向过程: 一切以事务的发展流程为中心. 面向对象: 一切以对象为中心. 一切皆为对象. 具体的某一个事务就是对象 打比方: 大象进冰箱 步骤: 第一步, 开门, 第二步, 装大 ...

  4. 为linux主机增加file description

    在benchmarked写的服务器的时候就遇到了too many file open 这个报错. 由于遇到过很多次了,所以知道应该是单机fd打满了. 首先来看看 机器最多支持多少fd cat /pro ...

  5. vue bug & data type bug

    vue bug & data type bug [Vue warn]: Invalid prop: type check failed for prop "value". ...

  6. Promise是什么?

    一. Promise是什么? Promise是一种异步操作的解决方案,将写法复杂的传统的回调函数和监听事件的异步操作,用同步代码的形式表达出来. 避免了多级异步操作的回调函数嵌套. Promise最早 ...

  7. 一、.NET Core MVC 项目结构模板

    一.图文描述,开口干 二.文件结构:  wwwroot 首先,Razor Pages项目中多了一个wwwroot的文件夹,这个文件夹中,主要存放网站的静态资源,如css,网站图片资源文件,js文件,三 ...

  8. 【python练习题】程序16

    #题目:输出指定格式的日期. import time print (time.strftime('%Y:%m:%d %X',time.localtime(time.time())))

  9. 【C/C++】求解线性方程组的雅克比迭代与高斯赛德尔迭代

    雅克比迭代: /* 方程组求解的迭代法: 雅克比迭代 */ #include<bits/stdc++.h> using namespace std; ][]; ]; void swapA( ...

  10. 自定义django-admin命令

    我们可以通过manage.py编写和注册自定义的命令. 自定义的管理命令对于独立脚本非常有用,特别是那些使用Linux的crontab服务,或者Windows的调度任务执行的脚本.比如,你有个需求,需 ...