`
marszgl
  • 浏览: 53617 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JSF组件开发指南

    博客分类:
  • java
阅读更多
JSF 组件模型

JSF 组件模型与 AWT GUI 组件模型类似。它有事件和属性,就像 Swing 组件模型一样。它也有包含组件的容器,容器也是组件,也可以由其他容器包含。从理论上说,JSF 组件模型分离自 HTML 和 JSP。JSF 自带的标准组件集里面有 JSP 绑定,可以生成 HTML 渲染。



JSF 组件的示例包括日历输入组件和 HTML 富文本输入组件。您可能从来没时间去编写这样的组件,但是如果它们已经存在,那会如何呢?通过把常用功能变成商品,组件模型降低了向 Web 应用程序添加更多功能的门槛。



组件的功能通常围绕着两个动作:解码和编码数据。

解码(decoding) 是把进入的请求参数转换成组件的值的过程。

编码 (encode) 是把组件的当前值转换成对应的标记(也就是 HTML)的过程。



JSF 框架提供了两个选项用于编码和解码数据

使用直接实现 方式,组件自己实现解码和编码

使用委托实现 方式,组件委托渲染器进行编码和解码。

如果选择委托实现,可以把组件与不同的渲染器关联,会在页面上以不同的方式渲染组件;例如多选列表框和一列复选框。因此,JSF 组件由两部分构成:组件和渲染器。JSF 组件 类定义 UI 组件的状态和行为;渲染器 定义如何从请求读取组件、如何显示组件 —— 通常通过 HTML 渲染。渲染器把组件的值转换成适当的标记。事件排队和性能验证发生在组件内部。

在图 1 中可以看到数据编码和解码出现在 JSF 生命周期中的什么阶段




图 1. JSF 生命周期和 JSF 组件



所有 JSF 组件的基类是 UIComponent。在开发自己的组件时,需要继承 UIComponentBase,它扩展了 UIComponent 并提供了 UIComponent 中所有抽象方法的默认实现。组件拥有双亲和标识符。每个组件都关联着一个组件类型,组件类型用于在 face 的上下文配置文件(faces-config.xml)中登记组件。可以用 JSF-EL (表达式语言)把 JSF 组件绑定到受管理的 bean 属性。可以把表达式关联到组件上的任何属性,这样就允许用 JSF-EL 设置组件的属性值。在创建使用 JSF-EL 绑定的组件属性时,需要创建值绑定表达式。在调用绑定属性的 getter 方法时,除非 setter 方法已经设置了值,否则 getter 方法必须用值绑定获得值。组件可以作为 ValueHolder 或 EditableValueHolder。ValueHolder 与一个或多个 Validator 和 Converter 相关联;所以 JSF UI 组件也与 Validator 和 Converter 关联



像表单字段组件这样的组件拥有一个 ValueBinding,它必须绑定到 JavaBean 的读写属性。组件可以调用 getParent 方法访问它们的双亲,也可以调用 getChildren 方法访问它们的子女。组件也可以有 facet 组件,facet 组件是当前组件的子组件,可以调用 getFacets 方法访问它,这个方法返回一个映射。Facets 是著名的子组件。

这里描述的许多组件的概念将会是接下来展示的示例的一部分,所以请记住它们!





提示!

在许多情况下,可以在保持组件本身不变的情况下,通过改变渲染而简化开发过

程。在这些情况下,可以编写定制渲染器而不是定制组件。



JSF 组件的LoginComponent



我们用一个又好又容易的示例来开始 JSF 组件的开发:

下面是我要采取的步骤:



1. 扩展 UIComponent

创建一个类,扩展 UIComponent

保存组件状态

用 faces-config.xml 登记组件

2. 创建定制标记,继承 UIComponentTag

覆盖 encode

覆盖 decode

用 faces-config.xml 登记渲染器

3. 定义渲染器或者内联地实现它

返回渲染器类型

返回组件类型

设置可能使用 JSF 表达式的属性





详细结构:由component 、model 、renderer 、taglib 、utils(可选) 组成。




Step 1 扩展Components

具体代码请参考Sample , 这里只叙述一些重要的方法

第一个类是LoginComponent.java LoginComponent是整个组件开发的核心类。

它必须继承一个UIComponent ,这里它继承的是UIInput

每个组件都关联着一个组件类型,组件类型用于在 face 的上下文配置文件(faces-config.xml)中登记组件






  <component>

    <component-type>sonic.Loginr</component-type>

    <component-class>mycomponents.component.LoginComponent</component-class>

  </component>

 

JSF提供了数值绑定机制,使得在Faces标记中访问bean property 很容易,其原理是用 JSF-EL (表达式语言)把 JSF 组件绑定到受管理的 bean 属性。可以把表达式关联到组件上的任何属性,

这样就允许用 JSF-EL 设置组件的属性值,比如:

<h:inputText id=”user” value=”#{ userBean .username}” />

Valuebinding 在解析userBean.username这个keypath的时候,会使用反射(reflection)访问UserBean中的username property、如果没有就为null.。





在创建使用 JSF-EL 绑定的组件属性时,需要创建值绑定表达式。在调用绑定属性的 getter 方法时,除非 setter 方法已经设置了值,否则 getter 方法必须用值绑定获得值。




//get The UserName value

    public String getUserText() ...{

        if(this.userText!=null)

             return this.userText;

        else...{

           ValueBinding vb = this.getValueBinding("userText");

           if(vb==null)

                return "";

            else

                return (String)vb.getValue(getFacesContext());

        }

    }

   



  //Get the Password value

    public String getPswText() ...{

        if(this.pswText!=null)

             return this.pswText;

        else...{

          ValueBinding vb = this.getValueBinding("pswText");

           if(vb == null)

                return "";

            else

                return (String)vb.getValue(getFacesContext());

        }

    }




所有 JSF 组件的基类是 UIComponent。在开发自己的组件时,需要继承 UIComponentBase,它扩展了 UIComponent 并提供了 UIComponent 中所有抽象方法的默认实现。



它的主要作用就是保存和恢复组件的状态。由saveStore(),restoreState() 两个方法来执行。

getFamily()方法主要是返回在faces-config.xml中定义了相关联的渲染器






<render-kit>

       <renderer>

          <component-family>sonic.Loginr</component-family>

          <renderer-type>sonic.Loginr</renderer-type>

          <renderer-class>mycomponents.renderer.LoginRenderer</renderer-class>

       </renderer>

</render-kit>



UIComponent 类的一个职责是为其绑定的model property 提供UI表示(UIComponent&Render其实对应MVC中的View)。 UIComponent定义有value property , 用了缓冲在请求相应中inbound(接受请求值) , outbound(处理后的请求值)这个property 还在

Apply Request Values 阶段暂时保存了对提交的值转换之后的结果,最终,组件value字段的内容会在

Update Model Value 阶段 被转换到对应的bean property .



由于,我的组件是一个复合组件,有2个textbox , 他不能在updateModel()这个方法中自动绑定与bean相关联的属性,所以在这个里面就要重载updateModel(),手动绑定属性到bean中。


       public void updateModel(FacesContext context) ...{

              // TODO Auto-generated method stub

              ValueBinding vb = this.getValueBinding("userText");

              if (vb != null)...{

                     vb.setValue(context,this.getUsername());

                     this.setUsername(null);

              }

             
              ValueBinding vb2 = this.getValueBinding("pswText");

              if (vb2 != null)...{

                     vb2.setValue(context,this.getPassword());

                     this.setPassword(null);

              }

              super.updateModel(context);

       }








Step 2 创建一个LoginTag为 LoginComponent创建定制标记


l  LoginTag 必须 extends UIComponentTag

l  在web.xml中的 <jsp-config></jsp-config>中添加标记定位


<jsp-config>

            <taglib>

              <taglib-uri>http://www.ygsoft.com</taglib-uri>

               <taglib-location>/WEB-INF/login.tld</taglib-location>

            </taglib>

</jsp-config>






l  添加login.tld


setProperty()这个方法允许这个代码允许 LoginComponent的 value 属性绑定到后台 bean


    protected void setProperties(UIComponent component) ...{

        /**//* have to call the super class */

        super.setProperties(component);

        CompUtils.setAttribute(component,"userLabel",userLabel);

        CompUtils.setAttribute(component,"pswLabel",pswLabel);

        CompUtils.setAttribute(component,"userText",userText);

        CompUtils.setAttribute(component,"pswText",pswText);

        CompUtils.setAttribute(component,"loginSuccess",loginSuccess);

        CompUtils.setAttribute(component,"loginFailure",loginFailure);

        CompUtils.setAttribute(component,"errorStyleClass",errorStyleClass);

        ((LoginComponent)component).setRequired(true);

}



       public final static void setAttribute(UIComponent component,

                     String attrName, String value) ...{

              if (value != null) ...{

                     if (Util.isVBExpression(value)) ...{

                            ValueBinding vb = Util.getValueBinding(value);

                            component.setValueBinding(attrName, vb);

                     } else ...{

                            component.getAttributes().put(attrName, value);

                     }

              }

       }




errorStyleClass属性不是setValueBinding的,它们被添加到 JSF 组件的属性映射 中。Renderer类会使用属性映射去渲染类和样式属性。这个设置允许特定于 HTML 的代码从组件脱离所以是用getAttributes().put(attrName, value);来设定的



最后是把渲染器映射到组件


    public String getComponentType() {

        return "sonic.Loginr";

}   

    <component>

         <component-type>sonic.Loginr</component-type>

         <component-class>mycomponents.component.LoginComponent</component-class>

</component>

============================================================================

    public String getRendererType() {

        return "sonic.Loginr";

}   

  <render-kit>

    <renderer>

        <component-family>sonic.Loginr</component-family>

        <renderer-type>sonic.Loginr</renderer-type>

        <renderer-class>mycomponents.renderer.LoginRenderer</renderer-class>

    </renderer>

</render-kit>








Step 3 定义一个独立渲染器LoginRender


其实渲染器可以在UIComponent里面的,这里使用的是使用委托实现方式,组件委托渲染器进行编码和解码。

渲染器的作用其实主要是html的输出,其中的重点是encodeBegin, decode



LoginComponent组件是一个 UIInput 组件,这意味着它接受输入(UIOutPut组件不用decode),所以 必须 进行解码。decode方法可以从会话、cookie、头、请求等处读取值。在大多数请问下,decode方法只是像上面那样从请求参数读取值。Decode 方法负责从请求取得输入,并解码成适合组件的数据



Encode 编码,编成HTML码,Rander类里面就是encodeBegin , encodeEnd这里就是写在encodeBeanin里面,其实对应自定义标签里面的doStartTag() , doEndTag();

encodeBegin()里面主要是用 ResponseWriter

响应写入器(javax.faces.context.ResponseWriter)可以容易地处理 HTML 这样的标记语言






ResponseWriter writer = context.getResponseWriter();

比如:

       writer.startElement("table", component);

              writer.writeAttribute("width", "60%", null);

              writer.writeAttribute("align", "center", null);

              writer.writeAttribute("border", "0", null);

              writer.writeAttribute("cellpadding", "0", null);

              writer.endElement("table");



生成的HTML代码就是


<table width=”60%” align=”center” border=”0” cellspacing=”1”></table>


分享到:
评论

相关推荐

    JSF 组件开发.rar

    在"JSF组件开发.rar"这个压缩包中,我们很可能会找到关于如何设计、实现和使用JSF自定义组件的详细教程或指南。 ### 一、JSF组件基础 1. **组件层次结构**:JSF组件树是应用程序的核心,每个组件都有属性、事件和...

    如何写自定义得JSF组件(en)

    如何撰写自定义JSF组件:全面解析与实践指南 引言 JavaServer Faces(简称JSF)是一项基于组件的方法构建用户界面的技术。它通过UI组件作为构建模块简化了开发过程,大幅度减少了代码量,并允许在不同项目间重复...

    ajax4jsf中文用户指南

    Ajax4JSF组件库 Ajax4JSF提供了一系列的组件,包括但不限于: - `a4j:ajaxListener`:监听JSF事件并触发Ajax请求。 - `a4j:region`:定义页面上的Ajax作用域。 - `a4j:commandLink` 和 `a4j:commandButton`:替代...

    JSF1.2日历组件

    2. **自定义组件开发**:在JSF 1.2中,开发者可以通过实现UIComponent接口并重写必要的方法来创建自定义组件。组件需要定义属性、事件处理和渲染逻辑。此外,还需要提供一个对应的标签库描述文件(TLD或XML)以便在...

    JSF实例开发教程(经典入门到精通)

    **JSF(JavaServer Faces)** 是一个Java平台上的用户界面框架,专为构建Web应用程序而设计。它提供了一种模型-视图...教程中的"jsf教程.pdf"很可能是包含这些实例和详细步骤的详细指南,是学习JSF不可或缺的参考资料。

    Ajax4JSF用户指南

    这种页面范围的Ajax支持使得你可以定义一个触发Ajax请求的事件,并在接收到客户端事件后,根据需要更新服务器端数据,同步JSF组件树以反映页面变化。 Ajax4JSF的组件库包括一系列的标签,如: 1. `a4j:ajax...

    JSF核心编程学习指南

    在JSF中,视图通常由JSF组件和JSP页面组成,控制器则由后台Bean执行,模型则是业务逻辑的载体。通过JSF,开发者可以清晰地划分MVC三层架构,避免像使用Struts那样可能出现的混淆。 总的来说,JSF提供了一种组件化的...

    JSF 2.0 开发资料

    ### JSF 2.0 开发资料:详细解析与实用指南 #### 一、JSF 2.0 概览 JavaServer Faces (JSF) 2.0 是 Java 平台上的一种用于构建用户界面的标准组件框架。它作为 Java EE 的一部分,在 JSF 2.0 版本中进行了大量的...

    jsf入门指南,网页版,特别适合新手学习,我刚接触jsf就是看得这个

    **二、JSF组件** JSF组件是构成JSF界面的基本元素,类似于HTML元素。它们可以是简单的输入字段,也可以是复杂的表格或表单。JSF提供了一个丰富的组件库,例如`h:inputText`(文本输入)、`h:commandButton`(提交...

    初探JSF框架入门指南,资源由网络分享整理,如有侵权请联系我

    JavaScript Faces (JSF) 是Java平台上的一种用于构建用户界面的模型-视图-控制器..."第3章.pdf"通常会深入到JSF组件库。JSF提供了一系列内置的UI组件,如文本输入框、按钮、表单等,这些组件可以直接在Facelets模板中

    ajax4jsf 用户指南

    指南还可能包含如何在各种集成开发环境中配置和使用 Ajax4jsf 的信息。 ### 8. Exadel VCP 和 Ajax4jsf Exadel VCP 可能是与 Ajax4jsf 相关的一个开发工具或版本控制系统。 ### 9. Web 上的资源 最后,提供了在线...

    jsf中文使用教程jsf中文使用教程

    2. **PrimeFaces** 是一个流行的JSF组件库,提供了许多美观的UI组件。 在"JSF中文教程.chm"中,你可能会找到以下内容: 1. JSF的基本概念和架构介绍。 2. 如何设置和运行JSF项目。 3. 创建和使用Managed Beans的...

    A4J ajax4jsf中文指南 chm

    A4J提供了一系列的JSF组件,如`&lt;rich:component&gt;`、`&lt;a4j:commandButton&gt;`和`&lt;a4j:ajax&gt;`等,它们简化了AJAX功能的集成。例如: - `&lt;a4j:commandButton&gt;`:这是一个具有AJAX功能的命令按钮,可以在点击后仅更新部分...

    ajax 4jsf用户指南中文版

    #### 四、Ajax4JSF组件库 - **组件库**:Ajax4jsf提供了一系列内置的JSF标签库,用于简化Ajax功能的实现。 - **a4j:ajaxListener**:用于监听Ajax事件。 - **a4j:region**:定义区域内的元素响应Ajax事件。 - **...

    jsf介绍和例子

    5. **EL(Expression Language)** - EL是用于访问应用程序上下文中的属性和方法的简洁表达式语言,与JSF组件紧密集成。 **京东JSF服务框架**: 京东可能在其内部开发了一个定制版的JSF框架,以适应其电商平台的...

    JSF入门

    通过这个入门指南,你可以学习到JSF的基础知识,包括如何创建简单的JSF应用程序、理解和使用JSF组件、配置和管理Managed Beans,以及掌握JSF生命周期和Ajax支持。继续深入研究,你将能够利用JSF构建高效、可维护的...

    JSF2和RICHFASES4使用指南

    JSF2和RICHFASES4使用指南,JSF(Java Server Faces)是JCP标准化组织通过的Web应用开发标准框架,RichFaces是RedHat公司的JBoss社区开发的一套基于JSF的UI组件库,支持异步请求功能

    Richfaces组件使用指南

    测试方面,尽管文中没有详细介绍,但RichFaces计划提供一个自动化测试工具,生成测试用例以加速组件开发,同时测试组件和服务端及客户端的JavaScript功能,无需部署到Servlet容器。 要使用RichFaces 3.3.3,你需要...

Global site tag (gtag.js) - Google Analytics