一、框架简介
JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架,它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。
典型的JSF应用程序包含下列部分:
一组JSP页面
一组后台bean(为在一个页面上的UI组件定义的属性和函数的JavaBean组件)
应用程序配置资源文件(定义页面导航规则、配置bean和其它的自定对象,如自定义组件)
部署描述文件(web.xml)
一组由应用程序开发者创建的自定义对象(有可能)
一些可能包含自定义组件、约束、转换器或者监听器的对象
为在页面中表现自定义对象的一组自定义tag
包含JSP页面的JSF应用程序也使用由为了表现UI组件和在页面上的其他对象的JSF技术而定义的标准的tag库。
二、JSF生命周期
JSF(JavaServer Faces)应用程序框架的简单程序是自动管理生命周期阶段,并允许您手动管理。JSF(JavaServer Faces)应用程序的生命周期从客户端对页面发出HTTP请求时开始,并在服务器响应页面时结束。
JSF生命周期分为两个主要阶段:
1. 执行阶段
在执行阶段,当第一次请求时,构建或恢复应用程序视图。 对于其他后续请求,执行其他操作,如应用请求参数值,对组件值执行转换和验证,受托管的bean
将使用组件值进行更新,并调用应用程序逻辑。
执行阶段被进一步分成以下子阶段。
a:恢复视图阶段
当客户端请求一个JavaServer Faces页面时,JavaServer Faces实现开始恢复视图阶段。 在此阶段,JSF将视图中的组件构建为请求页面,线性事件处理程序和验证器的视图,并将视图保存在FacesContext实例中。
如果对该页面的请求是回发,那么与该页面相对应的视图已经存在于FacesContext实例中。 在此阶段,JavaServer Faces实现通过使用保存在客户端或服务器上的状态信息来还原视图。
b:应用请求值阶段
在此阶段,在回发请求期间恢复组件树。 组件树是表单元素的集合。树中的每个组件通过使用其decode(processDecodes())
方法从请求参数中提取其新值。 之后,该值将本地存储在每个组件上。
FacesContext.responseComplete()
方法。c:流程验证阶段
在此阶段,JavaServer Faces通过使用其validate()
方法来处理在组件上注册的所有验证器。 它检查指定验证规则的组件属性,并将这些规则与为组件存储的本地值进行比较。 JavaServer Faces还完成了没有将immediate
属性设置为true
的输入组件的转换。
renderResponse
方法,则JavaServer Faces实现将跳过“渲染响应”阶段。FacesContext.responseComplete
方法。d:更新模型值阶段
确保数据有效后,它遍历组件树,并将相应的服务器端对象属性设置为组件的本地值。 JavaServer Faces实现只更新输入组件的value
属性指向bean
属性。 如果本地数据无法转换为bean
属性指定的类型,生命周期将直接前进到“渲染响应”阶段,以便重新呈现页面并显示错误。
renderResponse()
方法,则JavaServer Faces实现将跳过“渲染响应”阶段。FacesContext.responseComplete()
方法。e:调用应用阶段
在此阶段,JSF处理应用程序级事件,例如提交表单或链接到另一个页面。
现在,如果应用程序需要重定向到其他Web应用程序资源或生成不包含任何JSF组件的响应,则可以调用FacesContext.responseComplete()
方法。
之后,JavaServer Faces实现将控制转移到“渲染响应”阶段。
f:渲染响应阶段
这是JSF生命周期的最后阶段。 在此阶段,JSF将构建视图并将权限委托给相应的资源来呈现页面。
如果页面包含h:message
或h:messages
标签,页面上会显示任何排队的错误消息。
在渲染视图的内容之后,保存响应的状态,以便后续请求可以访问它。 恢复视图阶段可以使用保存的状态。
2. 渲染阶段
在此阶段,请求的视图作为对客户端浏览器的响应。 视图渲染是以HTML或XHTML生成输出的过程。 所以,用户可以在浏览器看到它。
在渲染过程中采取以下步骤。
index.xhtml
网页进行初始请求时,编译应用程序。EL
表达式表示的组件和与其关联受托管bean
属性填充组件树。三、JSF托管Bean
托管bean它是一个纯Java类,它包含一组属性和一组getter
,setter
方法。
以下是托管bean方法执行的常见功能:
1、JSF托管Bean示例:
请看看下面一段示例代码 :
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
您可以通过以下方式使用此bean
。
a:通过XML文件配置托管Bean:
user
User
session
在xml文件配置bean
是比较旧方法。 在这种方法中,我们必须创建一个名为faces-config.xml
的xml文件,JSF提供了配置bean
的标签。
在上面的例子中,我们列出了bean-name
,bean-class
和bean-scope
。 所以,它可以在项目中访问。
b:使用注释配置托管Bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean // Using ManagedBean annotation
@RequestScoped // Using Scope annotation
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
类中的@ManagedBean
注解自动将该类注册为JavaServer Faces的资源。 这种注册的托管bean在应用程序配置资源文件中不需要托管bean配置项。
@ManagedBean
将bean标识为名称属性中指定的名称的托管bean。如果未指定name
属性,那么托管bean名称将默认为简单的类名称,其中第一个字母小写。 在我们的情况下是helloWorld
。
如果eager
设置为“true
”,则在请求之前创建托管bean。如果使用“lazy
”初始化,只有在请求时才会创建bean。
这是应用程序配置资源文件方法的替代方法,并减少配置托管bean的任务。 @RequestScoped
注释用于提供托管的范围。 您可以使用注解来定义bean将被存储的范围。
@ManagedBean(name = "helloWorld", eager = true)
@RequestScoped
public class HelloWorld {
@ManagedProperty(value="#{message}")
private Message message;
...
}
您可以对bean类使用以下范围:
@ManagedBean
中设置属性eager = true
,并在Web应用程序关闭时被销毁)。java.util.Map
,自定义范围很少使用。(bean只要在为此范围创建的自定义Map中的bean的条目生效)。急切管理Bean
托管bean
默认是懒惰的。 这意味着,只有在从应用程序发出请求时才会去实例化bean。
如果想自动提前强制将bean
实例化,那么可在应用程序启动时,可以强制将bean
实例化并放置在应用程序(@ApplicationScoped
)范围内。您需要将托管 bean 的eager
属性设置为true
,如以下示例所示:
@ManagedBean(eager=true)
@ManagedProperty注释
JSF是一个简单的静态依赖注入(DI)框架。 @ManagedProperty
注释标记被托管的bean的属性以注入另一个受托管的Bean。
2、如何进行bean注入
我们先定义一个消息bean,它有一个字符串属性来存储消息。
@ManagedBean(name="message")
@SessionScoped
public class MessageBean implements Serializable {
private static final long serialVersionUID = 1L;
private String sayWelcome = "Welcome to JSF 2.0";
然后我们再定义另一个托管bean,并使用@ManagedProperty
注解注入MessageBean
。
@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
@ManagedProperty(value="#{message}")
private MessageBean messageBean;
public void setMessageBean(MessageBean messageBean) {
this.messageBean = messageBean;
}
实例:
创建一个名为: InjectManagedBeans 的工程,并加入以下文件代码。
以下是文件:UserBean.java 中的代码
package com.yiibai;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
@ManagedProperty(value="#{message}")
private MessageBean messageBean;
public void setMessageBean(MessageBean messageBean) {
this.messageBean = messageBean;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSayWelcome(){
//check if null?
if("".equals(name) || name ==null){
return "";
}else{
return messageBean.getSayWelcome() + name;
}
}
}
以下是是文件:index.xhtml 中的代码
以下是文件:MessageBean.java 中的代码
package com.yiibai;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean(name="message")
@SessionScoped
public class MessageBean implements Serializable {
private static final long serialVersionUID = 1L;
private String sayWelcome = "Welcome to JSF 2.0";
public String getSayWelcome() {
return sayWelcome;
}
public void setSayWelcome(String sayWelcome) {
this.sayWelcome = sayWelcome;
}
}
运行测试结果:
Tomcat启动完成后,在浏览器地址栏中输入以下URL。
http://localhost:8084/InjectManagedBeans/
运行结果如下所示