一、前言
在创建JSF的FacesContext的对象时,像之前绝大多数做法一样。
- 首先,在class的公共域声明并创建facesContext对象(未初始化);
FacesContext facesContext = FacesContext.getCurrentInstance();
然后,在方法中实例化上面创建的facesContext对象并调用该对象;
声明:JSF的FacesContext对象的实例化方式比较特别,它是在发起JSF请求时初始化facesContext对象的(正是因为这个原因导致报错,这一点在下一节里讲解)。
facesContext.addMessage(null,new FacesMessage("Hello!");
然而,部署完后报错:
17:27:10,839 ERROR [io.undertow.request] (default task-41) UT005023: Exception handling request to /labmanagement/home.jsf: javax.servlet.ServletException: javax.servlet.ServletException: java.lang.IllegalStateException
二、FacesContext简介
FacesContext是faces中经常用到的两个接口,对于每一个JSF请求,FacesServlet都会生成一个对应的FacesContext,然后在创建的Context中进行相关的操作。所以FacesContext对象只能在一个JSF请求的周期中产生,实际上它是调用静态的getCurrentInstance方法,返回当前的FacesContext实例。在”前言”部分调用该静态getCurrentInstance方法的作用域没有JSF请求,这也就导致了上文中出现IllegalStateException。
对于FacesContext的理解可以结合JPA中的persistence context进行理解。
三、FacesContext对象实例化
3.1 实例化方法一
参照”前言”部分,将
FacesContext facesContext = FacesContext.getCurrentInstance();
该方法的调用放在JSF的请求处理周期中,FacesServlet才能获取到FacesContext实例。
3.2 实例化方法二
使用CDI的依赖注入,向容器事先申请一个FacesContext(组件注入FacesContext对象facesContext),
@Inject
FacesContext facesContext;
然后在实际调用该FacesContext对象时调用即可。
facesContext.addMessage(null,new FacesMessage("Hello!");
四、CDI注入理解
4.1 方法一分析
上文中的方法一,
FacesContext facesContext = FacesContext.getCurrentInstance();
由于没有处于JSF的请求周期中,所以静态的getCurrentInstance方法无法获取该FacesContext实例,即该对象实际上是没有实例化的,所以后面也就没法调用了。
4.2 方法二分析
使用CDI的依赖注入,向容器事先申请一个FacesContext组件,此时并没有实例化。但是在后文调用这个组件时就能得到及时实例化。
(其实我也不理解)
五、完整代码
@Inject
StuffFacade stuffService;
facesContext.addMessage(null,new FacesMessage("Hello!");