当前位置: 代码迷 >> JavaScript >> 创造JSF自定义组件实例过程
  详细解决方案

创造JSF自定义组件实例过程

热度:510   发布时间:2012-09-23 10:28:10.0
创建JSF自定义组件实例过程
http://anoxia.blogbus.com/logs/6841632.html

在我们开始之前,首先下载Step0.zip,它是一个初始的工程,包含了JSF运行所需要的包。当程序运行时将显示bannerpage.jsp页面,我们将通过这个页面逐步展示自定义组件的创建过程,并达到最终的运行效果。效果图如下:



第一节、  自定义组件组成       首先我们将创建在页面上显示“Hello JSF Component”文字的简单组件,通过这个实例我们需要认识到自定义组件由那几部分组成。
一、页面显示代码

l         在HTML页面表述:
<div>Hello JSF Component</div>
l         在JSF页面表述:
<d:ticker>
<f:verbatim>Hello JSF Component</f:verbatim>
</d:ticker>
二、开始创建自定义组件

1、  第一步:实现标签库描述库
在WEB-INF下创建ticker.tld文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
  <taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>d</short-name>
    <uri>http://jsftutorials.com/</uri>
    <tag>
      <name>ticker</name>
      <tag-class>ticker.TickerTag</tag-class>
      <body-content>JSP</body-content>
    </tag>
  </taglib>
2、  第二步:创建标签属性处理类
新建ticker包并在其下创建TickerTag.java

package ticker;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;
public class TickerTag extends UIComponentTag{
public void release() {
                          // the super class method should be called
                          super.release();
          }
          protected void setProperties(UIComponent component) {
                          // the super class method should be called
                          super.setProperties(component);
          }
          public String getComponentType() {
                          return "ticker";
                          }
          public String getRendererType() {
                          // null means the component renders itself
                          return null;
          }
}
注意:

l         通常我们的属性处理类命名为:标签名+Tag。l         TickerTag需要继承UIConponentTag。l         getComponentType()方法返回组件类型名称,类型在faces-configz.xml中配置,稍后我们将看到。l         getRendererType()方法返回组件所需的呈现器类型。如果返回为空,那么组件将自我呈现。l         release()方法将在标签销毁时释放它所占用的资源。l         setProperties()方法是必须的,它将标签属性值绑定到组件中。
第三步:创建组件类

打开WEB-INF/faces-config.xml并且在其中写入配置信息

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
  <faces-config>
    <component>
      <component-type>ticker</component-type>
      <component-class>ticker.UITicker</component-class>
    </component>
    <lifecycle/>
    <application>
      <locale-config/>
    </application>
    <factory/>
  </faces-config>
创建ticker.UITicker类,组件类主要用来维护状态、呈现用户接口和处理输入。

package ticker;
import java.io.IOException;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
public class UITicker extends UIOutput {
          public void encodeBegin(FacesContext context) throws IOException {
                          ResponseWriter writer = context.getResponseWriter();
                          writer.startElement("div", this);
          }
          public void encodeEnd(FacesContext context) throws IOException {
                          ResponseWriter writer = context.getResponseWriter();
                          writer.endElement("div");
          }
}
注意:

组件类必须以UI+组件类型名命名

l         因为自定义组件没有输入,所以我们继承UIOutput类l         encodeBegin(FacesContext context)方法开始标签l         encodeEnd(FacesContext context)方法结束标签
第四步:使用自定义组件

打开bannerpage.jsp页面,并且将标签添加到JSP页面中

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jsftutorials.com/" prefix="d" %>
<html>
  <head>
    <title>Show Custom Component</title>
  </head>
  <body>
    <f:view>
      <d:ticker>
        <f:verbatim>Hello JSF Component</f:verbatim>
      </d:ticker>
    </f:view>
  </body>
</html>
注意:

l         URI属性是必须的,通常都认为它是一个URL,但它其实是一个标签的唯一标识。l         <f:verbatim>标签使用在自定义标签内是允许的,它的作用是将<div>作为HTML代码输出。
第五步:最后将工程添加到TOMCAT中,运行后可以看到在bannerpage.jsp页面的显示效果。我是在eclipse + myeclipse + tomcate环境测试。

三、组件调用关系图




1、  根据JSP页面上的URI值查找标签库2、  根据使用的标签在标签库中查找到相应标签3、  根据标签库中标签的信息查找到标签类4、  通过标签类在faces-config.xml中查找到对应处理类5、  通过处理类的encodeBegin方法和encodeEnd方法实现标签内容。第二节、      添加简单的属性
上一节中<div>标签没有任何样式,这一节我们将在自定义控件中加入简单的属性,通过加入css样式将<div>标签显示出来。

第一步、在JSP中添加标签的样式

打开jsp页面,在<d:ticker>自定义标签中添加style样式:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jsftutorials.com/" prefix="d" %>
<html>
          <head>
                          <title>Show Custom Component</title>
          </head>
          <body>
            <f:view>
              <d:ticker style="border:1px solid darkblue;width:100px">
                <f:verbatim>Hello JSF Component</f:verbatim>
              </d:ticker>
            </f:view>
          </body>  
</html>
第二步、在标签库ticker.tld中添加属性

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>d</short-name>
<uri>http://jsftutorials.com/</uri>
<tag>
  <name>ticker</name>
  <tag-class>ticker.TickerTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>style</name>
  </attribute>
</tag>
</taglib>
第三步、将属性添加到样式类

package ticker;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;


public class TickerTag extends UIComponentTag{
          String style;
         
          public String getStyle() {
                          return style;
          }

          public void setStyle(String style) {
                          this.style = style;
          }


          public void release() {
                          // the super class method should be called
                          super.release();
                          style = null ;
          }
         
          protected void setProperties(UIComponent component) {
                          // the super class method should be called
                          super.setProperties(component);

                          if(style != null)
                                         component.getAttributes().put("style", style);

          }

          public String getComponentType() {
                          return "ticker";
          }

          public String getRendererType() {
                          // null means the component renders itself
                          return null;
          }

}
注意:

1、  通过setStyle(String style)方法获取style的值。2、  通过getStyle()返回style的值。3、  在setProperties(UIComponent component)中将获得的style值绑定到组件属性中。4、  Release()中释放资源。
第四步、在标签处理类中将属性加入到标签

package ticker;
import java.io.IOException;


import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;


public class UITicker extends UIOutput {
         
          public void encodeBegin(FacesContext context) throws IOException {
                          ResponseWriter writer = context.getResponseWriter();
              writer.startElement("div", this);

              String style = (String)getAttributes().get("style");
              if (style!=null)
                       writer.writeAttribute("style", style, null);
          }

          public void encodeEnd(FacesContext context) throws IOException {
                          ResponseWriter writer = context.getResponseWriter();
              writer.endElement("div");
          }
}
注意:

       If(style!=null)是必要的,当你没有用到style属性时,如果没有使用该判断,将出现异常。

第五步、运行工程,我们可以看到div出现了深蓝色的边框。

第六步、改良css并继续添加属性

       通常我们通过定义CSS来控制显示效果,我们将页面代码变更了,以便更加灵活。并且我们通过类似的方法增加了一个styleclass属性
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://jsftutorials.com/" prefix="d" %>
<html>
          <head>
                          <title>Show Custom Component</title>
                          <style>
                             .banner {
                                            border: 1px solid darkblue;
                                            padding: 5px 5px 5px 5px;
                             }
                          </style>
          </head>
          <body>
            <f:view>
              <d:ticker styleClass="banner" style="width:100px">
                <f:verbatim>Hello JSF Component</f:verbatim>
              </d:ticker>
            </f:view>
          </body>  
</html>
Ticker.tld

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>d</short-name>
<uri>http://jsftutorials.com/</uri>
<tag>
  <name>ticker</name>
  <tag-class>ticker.TickerTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>style</name>
  </attribute>
  <attribute>
   <name>styleClass</name>
  </attribute>
</tag>
</taglib>
TickerTag.java

package ticker;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;


public class TickerTag extends UIComponentTag{
          String style;
          String styleClass;
         
          public String getStyle() {
                          return style;
          }

          public void setStyle(String style) {
                          this.style = style;
          }

          public String getStyleClass() {
                          return styleClass;
          }

          public void setStyleClass(String styleClass) {
                          this.styleClass = styleClass;
          }

          public void release() {
                          // the super class method should be called
                          super.release();
                          style = null ;
                          styleClass = null ;
          }
         
          protected void setProperties(UIComponent component) {
                          // the super class method should be called
                          super.setProperties(component);

                          if(style != null)
                                         component.getAttributes().put("style", style);

                          if(styleClass != null)
  相关解决方案