JSF笔记 – 托管Bean的详细介绍
本文由发表于6年前 | J2EE | 暂无评论 |  被围观 8,285 views+
1、托管Bean的介绍:1.1、绑定到一个组件的实例(bingding)的使用举例:2、托管Bean的编写:3、托管Bean的常用子标签:4、为应用增加导航规则:5、托管Bean的方法:① 处理导航的方法② 处理Action事件的方法
下面是一个使用actionListener属性的例子:
③ 处理Value Change事件的方法④ 处理输入校验的方法6、在托管Bean中保存和获取Session中的数据:
下面使用第二种方式实现:
6.1、通过FacesContext访问应用环境:
FacesContext接口包含的方法:
使用举例:
7、托管Bean的分类:
下面演示第一种方式的使用:
8、初始化托管Bean的属性:
1、托管Bean的介绍:

托管Bean的基本功能:

提供一组属性与页面中UI组件对应;
提供一组对页面组件执行功能的方法。

托管Bean可以绑定的形式:

绑定到一个组件的值(value)
绑定到一个组件的实例(bingding)
绑定到一个转换器实例(<f:converterXxx>)
绑定到一个验证器实例(<f:validatorXxx>)
绑定到一个监听器实例(<f:xxxListener>)
1.1、绑定到一个组件的实例(bingding)的使用举例:

在show.jsp页面中添加如下组件:

<f:view>
        <h3>组件显示</h3>
        <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:

<managed-bean>
        <!-- 指定Bean名称 -->
        <managed-bean-name>show</managed-bean-name>
        <!-- 指定Bean全限定类名 -->
        <managed-bean-class>com.itzhai.login.ShowBean</managed-bean-class>
        <!-- 指定托管Bean的有效范围:request,session,application --> 
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>

并不需要设置导航规则,因为方法中返回为null。

部署项目,启动服务器,访问:http://localhost:8080/JSFTest/show.jsf

在页面中点击组件显示按钮就会显示出组件了。

这个JSF应用有点类似于Ajax,但是并没有采用Ajax技术:

依然以同步方式提交请求
视图状态是保存在服务器端的,这样,即使客户端刷新页面,显示的效果依然存在。
JSF应用通过在托管Bean中变成控制指定的UI组件,这种方式比Ajax灵活性差。
2、托管Bean的编写:

与普通的Java Bean一样,为其提供一个无参构造函数,每个属性提供getter和setter方法。

3、托管Bean的常用子标签:
<!-- 配置托管Bean -->
<managed-bean>
    <!-- 指定Bean名称 -->
    <managed-bean-name>login</managed-bean-name>
    <!-- 指定Bean全限定类名 -->
    <managed-bean-class>com.itzhai.login.LoginBean</managed-bean-class>
    <!-- 指定托管Bean的有效范围:request,session,application --> 
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
4、为应用增加导航规则:
<navigation-rule>
    <!-- 导航规则的输入页面 -->
    <from-view-id>/login.jsp</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/index.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
        <from-outcome>failure</from-outcome>
        <to-view-id>/login.jsp</to-view-id>
    </navigation-case>
</navigation-rule>

其配置类似于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" %>
<html>
<head>
    <title>Login</title>
</head>
<body>                   
    <!-- 使用JSF视图输出 -->
    <f:view>
        <h3>ActionEvent Test</h3>
        <h:form id="actionEventForm">
            <h:inputText binding="#{actionEvent.eventTest }"></h:inputText>
            <h:commandButton actionListener="#{actionEvent.process }" value="测试"></h:commandButton>
        </h:form>
    </f:view>
</body>
</html>

接下来编写托管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:

<managed-bean>
    <!-- 指定Bean名称 -->
    <managed-bean-name>actionEvent</managed-bean-name>
    <!-- 指定Bean全限定类名 -->
    <managed-bean-class>com.itzhai.login.ActionEventBean</managed-bean-class>
    <!-- 指定托管Bean的有效范围:request,session,application --> 
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

在faces-confg-nav.xml设置导航规则,这里也可不用设置,因为页面没有跳转。

<navigation-rule>
    <!-- 导航规则的输入页面 -->
    <from-view-id>/actioneventtest.jsp</from-view-id>
</navigation-rule>

在web.xml中设置JSF参数:

<context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <!-- 程序状态保存在服务器端 -->
        <param-value>server</param-value>
    </context-param>

这个程序必须设置把程序状态保存在服务器端,否则会出错:

严重: 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中进行如下设置:

<managed-bean>
    <!-- 指定Bean名称 -->
    <managed-bean-name>userbean</managed-bean-name>
    <!-- 指定Bean全限定类名 -->
    <managed-bean-class>com.itzhai.login.UserBean</managed-bean-class>
    <!-- 指定托管Bean的有效范围:request,session,application --> 
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

假如LoginBean中需要获取Session中保存的UserBean,可以在faces-config-beans配置中注入参数:

<managed-bean>
    <!-- 指定Bean名称 -->
    <managed-bean-name>loginbean</managed-bean-name>
    <!-- 指定Bean全限定类名 -->
    <managed-bean-class>com.itzhai.login.LoginBean</managed-bean-class>
    <!-- 指定托管Bean的有效范围:request,session,application --> 
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>userbean</property-name>
        <value>#{userbean}</value>
    </managed-property>
</managed-bean>
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 -->
<managed-bean>
    <managed-bean-name>userbean</managed-bean-name>
    <managed-bean-class>com.itzhai.login.UserBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>   
<!-- 配置controller-bean -->
<managed-bean>
    <managed-bean-name>userControllerBean</managed-bean-name>
    <managed-bean-class>com.itzhai.login.UserControllerBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>userBean</property-name>
        <value>#{userbean }</value>
    </managed-property>
</managed-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" %>
<html>
<head>
    <title>Login</title>
</head>
<body>                   
    <!-- 使用JSF视图输出 -->
    <f:view>
        <h3>back-bean Test</h3>
        <h:form id="actionEventForm">
            <h:inputText binding="#{userbean.username }"></h:inputText>
            <h:commandButton actionListener="#{userControllerBean.valid }" value="测试"></h:commandButton>
        </h:form>
    </f:view>
</body>
</html>
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文件中进行初始化:

<managed-bean>
    <managed-bean-name>initparabean</managed-bean-name>
    <managed-bean-class>com.itzhai.bean.InitParaBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <!-- 初始化String类型 -->
    <managed-property>
        <property-name>name</property-name>
        <property-class>java.lang.String</property-class>
        <value>音乐列表</value>
    </managed-property>
    <!-- 初始化Map类型 -->
    <managed-property>
        <property-name>music</property-name>
        <map-entries>
            <key-class>java.lang.String</key-class>
            <value-class>java.lang.String</value-class>
            <map-entry>
                <key>蜗牛</key>
                <value>周杰伦</value>
            </map-entry>
        </map-entries>
    </managed-property>
    <!-- 初始化List类型 -->
    <managed-property>
        <property-name>type</property-name>
        <list-entries>
            <value>folk music</value>
        </list-entries>
    </managed-property>
</managed-bean>

这样在页面中就可以直接使用这个托管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" %>
<html>
<head>
    <title>Login</title>
</head>
<body>                   
    <!-- 使用JSF视图输出 -->
    <f:view>
        <h3>InitPara Test</h3>
        <h:outputText value="#{initparabean.name }" />
        <h:outputText value="#{initparabean.music['蜗牛'] }" />
        <h:outputText value="#{initparabean.type }" />
    </f:view>
</body>
</html>

启动服务器,访问:http://localhost:8080/JSFTest/initparatest.jsf 即可。

除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/jsf-notes-detailed-description-of-managed-bean.html
关键字: ,
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2011 12/2
如果您有更好的原创技术博文或者观点,欢迎投稿:admin@itzhai.com,或者关注订阅左侧浮动面板的微信号订阅IT宅itread)发送消息。
文章评论
    没有评论
给我留言

有人回复时邮件通知我
J2EE的相关文章
随机文章 本月热门 热评
1 SortedMap接口的实现类TreeMap介绍和实现Comparator自定义比较器 2011/10/16
2 Java Web笔记汇总 | IT宅文章归档 AD 2011/11/14 2011/11/14
3 Java源码分析 – Thread线程类源码分析 2011/10/23
4 据说这套试题对于软考很有帮助,大家可以看看 2011/4/26
5 打印网页内容的Javascript代码实现 2011/9/17
6 ExtJS根据后台数据动态创建CheckboxGroup的方法 2011/10/2
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
猜您喜欢
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.