1、托管Bean的介绍:
托管Bean的基本功能:
提供一组属性与页面中UI组件对应; 提供一组对页面组件执行功能的方法。
托管Bean可以绑定的形式:
绑定到一个组件的值(value) 绑定到一个组件的实例(bingding) 绑定到一个转换器实例(<f:converterXxx>) 绑定到一个验证器实例(<f:validatorXxx>) 绑定到一个监听器实例(<f:xxxListener>)
1.1、绑定到一个组件的实例(bingding)的使用举例:
在show.jsp页面中添加如下组件:
<f:view>
组件显示
<h:form id=“loginForm”>
<h:inputText binding=“#{show.bindingTest }”></h:inputText>
<h:commandButton action=“#{show.setBinding }” value=“显示”></h:commandButton>
</h:form>
</f:view>
在托管Bean中添加如下属性并添加setBinding方法,此方法用于设置组件实例的显示:
public class ShowBean {
private HtmlInputText bindingTest;
public HtmlInputText getBindingTest() {
return bindingTest;
}
public void setBindingTest(HtmlInputText bindingTest) {
this.bindingTest = bindingTest;
}
public String setBinding(){
bindingTest.setValue("Java");
bindingTest.setStyle("color:#cfdcff");
return null;
}
}
在faces-config-beans.xml配置文件中配置托管Bean:
并不需要设置导航规则,因为方法中返回为null。
部署项目,启动服务器,访问:http://localhost:8080/JSFTest/show.jsf
在页面中点击组件显示按钮就会显示出组件了。
这个JSF应用有点类似于Ajax,但是并没有采用Ajax技术:
依然以同步方式提交请求 视图状态是保存在服务器端的,这样,即使客户端刷新页面,显示的效果依然存在。 JSF应用通过在托管Bean中变成控制指定的UI组件,这种方式比Ajax灵活性差。
2、托管Bean的编写:
与普通的Java Bean一样,为其提供一个无参构造函数,每个属性提供getter和setter方法。
3、托管Bean的常用子标签:
<!-- 配置托管Bean -->
<!-- 指定Bean名称 -->
<!-- 指定Bean全限定类名 -->
<!-- 指定托管Bean的有效范围:request,session,application -->
4、为应用增加导航规则:
其配置类似于Struts2中Action的配置。
5、托管Bean的方法:
托管Bean的方法主要有如下几种:
① 处理导航的方法
通常用comandButton或者commandLink两个标签中的action属性将单击事件绑定到托管Bean内处理导航的方法。
处理的方法名格式必须为:
public String xxx()
其返回值必须是String类型,这个返回值是一个逻辑视图,JSF导航规则将会根据该逻辑视图导航到真实的物理视图。
② 处理Action事件的方法
通常用commandButton或者commandLink两个标签中的actionListener属性将单击事件绑定到托管Bean内处理Action事件的方法。
处理的方法格式必须为:
public void xxx(ActionEvent ae)
该方法被触发时,该形参就代表了触发该方法的事件对象。
对于处理Action事件的方法而言,它没有返回值,因此它不会导致应用导航到其他页面,但程序可以通过该方法来改变应用的状态,从而改变该页面的显示。
下面是一个使用actionListener属性的例子:
首先编写actioneventtest.jsp页面:
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ taglib prefix=“f” uri=“http://java.sun.com/jsf/core” %>
<%@ taglib prefix=“h” uri=“http://java.sun.com/jsf/html” %>
ActionEvent Test
接下来编写托管Bean ActionEventBean
public class ActionEventBean {
//绑定UI组件本身的属性
private HtmlInputText eventTest;
public HtmlInputText getEventTest() {
return eventTest;
}
public void setEventTest(HtmlInputText eventTest) {
this.eventTest = eventTest;
}
public ActionEventBean(){}
//编写处理Action事件的方法
public void process(ActionEvent ae){
eventTest.setValue(ae.getComponent());
eventTest.setStyle("color:#cfcfff");
}
}
在faces-config-beans.xml文件中配置托管Bean:
在faces-confg-nav.xml设置导航规则,这里也可不用设置,因为页面没有跳转。
在web.xml中设置JSF参数:
这个程序必须设置把程序状态保存在服务器端,否则会出错:
严重: JSF1054: (Phase ID: RENDER_RESPONSE 6, View ID: /actioneventtest.jsp) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@5c7734]
2011-12-2 15:31:55 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet FacesServlet threw exception
java.io.NotSerializableException: javax.faces.component.html.HtmlCommandButton
③ 处理Value Change事件的方法
④ 处理输入校验的方法
6、在托管Bean中保存和获取Session中的数据:
为了获取Session中的信息,有两种方法:
通过FacesContext获取Servlet API,使用原生的Servlet API访问session、applicatoin等; 通过使用session范围的托管Bean。
第一种方式简洁直观,但是导致了托管Bean与JSF API,Servlet API耦合,属于典型的侵入式设计,还停留在原始的MVC框架阶段,没有使用到JSF的优势。
下面使用第二种方式实现:
这里假如UserBean是需要放在Session范围中的,可以在faces-config-beans中进行如下设置:
假如LoginBean中需要获取Session中保存的UserBean,可以在faces-config-beans配置中注入参数:
6.1、通过FacesContext访问应用环境:
JSF页面在相应时,应用会创建一个新的视图并将它保存到FacesContext实例中,FacesContext实例包含了所有与处理请求、创建响应相关联的信息。接下来应用会获取该视图所需的对象引用,并调用FacesContext.renderResponse方法让应用开始向客户端生成响应。
FacesContext接口包含的方法:
ResponseStream getResponseStream()
ResponseWrite getResponseWriter()
ExternalContext getExternalContext()
其中的ExternalContext又提供了如下的方法:
getApplicationMap()
getInitParameter(String)
getInitParameterMap()
getRequestContextPath()
getRequestParameterMap()
getRequestServletPath()
getResponse()
getSession(boolean create)
getSessionMap()
redirect(String)
使用举例:
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.getSessionMap().put(“username”, “arthinking”);
7、托管Bean的分类:
**Backing-Bean:**相当于Struts1中的ActionForm **Controller-Bean:**相当于Struts1中的Action **Model-Bean:**充当应用状态模型,类似于上面的UserBean **Utility-Bean:**为应用的多个视图页面提供通用性质的工具。
使用Backing-Bean+Controller-Bean开发类似于Struts1的开发,使用Controller-Bean(即是把Backing-Bean中的数据也保存在这个Bean中)开发类似于Struts2中的开发。追求架构的话就使用第一种方式,追求实用的就推荐使用第二种方式。
而使用第一种方式与Struts1的区别在于:Strust1中Action通过execute方法以形参硬编码的方式来获取ActionForm,而JSF的controller-bean则通过依赖注入、以松耦合的方式来获取backing-bean。
下面演示第一种方式的使用:
编写backing-bean:
public class UserBean {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
编写controller-bean:
public class UserControllerBean {
private UserBean userBean;
public UserBean getUserBean() {
return userBean;
}
public void setUserBean(UserBean userBean) {
this.userBean = userBean;
}
public String valid(){
if(userBean.getUsername().equals("arthinking")
&& userBean.getPassword().equals("123")){
return "success";
}
return "failure";
}
}
接下来在faces-config-beans.xml配置文件中进行配置:
<!-- 配置backing-bean -->
<!-- 配置controller-bean -->
这样就可在页面中这样访问了:
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ taglib prefix=“f” uri=“http://java.sun.com/jsf/core” %>
<%@ taglib prefix=“h” uri=“http://java.sun.com/jsf/html” %>
back-bean Test
8、初始化托管Bean的属性:
可以在faces-config-bean.xml文件中配置托管Bean时,通过配置参数的值得方式进行初始化。
例如有一个InitParaBean的参数需要初始化,包含String、Map和List类型的参数:
public class InitParaBean {
private String name;
private Map<String, String> music;
private List<String> type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, String> getMusic() {
return music;
}
public void setMusic(Map<String, String> music) {
this.music = music;
}
public List<String> getType() {
return type;
}
public void setType(List<String> type) {
this.type = type;
}
}
可以在faces-config.xml文件中进行初始化:
这样在页面中就可以直接使用这个托管Bean了,编写initparatest.jsp 页面:
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ taglib prefix=“f” uri=“http://java.sun.com/jsf/core” %>
<%@ taglib prefix=“h” uri=“http://java.sun.com/jsf/html” %>
InitPara Test
启动服务器,访问:http://localhost:8080/JSFTest/initparatest.jsf 即可。