JSF2.0中自定义组件模型例子

在本篇介绍中,我们开始接触JSF2.0纳为标准的最重要的特性之一,facelets组件模型,整个组件模型的特性是很多的,我在本系列中只能做简单的介绍,并试图用比较简单的例子为大家揭示JSF2.0带给我们独特而快捷的开发体验。 
         在本篇中,主要揭示自定义组件的过程,在过程中,我还会给大家演示一下JSF2.0中其他的一些特性。现在自定义组件非常简单,下面就用一个例子来说明。

一、     创建一个应声器:
接上一篇中的工程TestJsf2.0,在其中加入如下文件:

echo.xhtml:
<!DOCTYPE   html   PUBLIC   "-//W3C//DTD   XHTML   1.0   Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html   xmlns="http://www.w3.org/1999/xhtml"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:ui="http://java.sun.com/jsf/facelets">
     <h:head>
         <title>测试简单的复合组件</title>
         <meta   http-equiv="keywords"   content="jsf2.0,组件,ajax"   />
         <meta   http-equiv="description"   content="测试简单的复合组件."   />
         <meta   http-equiv="content-type"   content="text/html;   charset=UTF-8"   />
     </h:head>
     <body>
         <div   id="header"   style="padding:100px   0   20px   100px;font-size:22px;font-weight:bold;border-bottom:solid   1px   red">
             这个应声器的作者是:#{echo.encoder.author}。
         </div>
         <div>
         <h:form   id="form"   style="padding:20px   0   20px   100px">
             <div   style="padding:20px;">
                 <span>请输入响应文字:</span>
                 <h:inputText   value="#{echo.echoText}"></h:inputText>
             </div>
             <div   style="padding-left:50px">
                             <h:commandButton   id="post"   style="padding:3px;width:100px;"   value="提交响应"   action="echo"/>
             </div>
         </h:form>
         </div>
         <h:panelGroup   id="after">
         <div   style="padding:20px   0   0   100px">
         响应:<h:outputText   id="echo"   value="#{echo.outText}"   escape="false"></h:outputText>
         </div>
         </h:panelGroup>
     </body>
</html>


InputEcho.java:

package   test;
import   javax.faces.bean.ManagedBean;
import   javax.faces.bean.SessionScoped;
@ManagedBean(name   =   "echo")
@SessionScoped
public   class   InputEcho   implements   java.io.Serializable   {
    
     private   static   final   long   serialVersionUID   =   9113785890193860362L;
     private   String   echoText;
     private   EchoEncoder   encoder;
    
     public   InputEcho()   {
         encoder   =   new   EchoEncoder();
     }

     /**
       *   @return   the   encoder
       */
     public   EchoEncoder   getEncoder()   {
         return   encoder;
     }

     /**
       *   @return   the   echoText
       */
     public   String   getEchoText()   {
         return   echoText;
     }
    
     public   String   getOutText()   {
         return   encoder.Encode(echoText);
     }

     /**
       *   @param   echoText   the   echoText   to   set
       */
     public   void   setEchoText(String   echoText)   {
         this.echoText   =   echoText;
     }
    
     public   void   echo()   {
     }
}    

EchoEncoder.java:
package   test;

public   class   EchoEncoder   implements   java.io.Serializable{
    
     private   static   final   long   serialVersionUID   =   8306351263183979293L;
     private   String   author   =   "pout";
    
     /**
       *   @return   the   author
       */
     public   String   getAuthor()   {
         return   author;
     }

     public   String   Encode(String   msg)   {
         return   msg.replaceAll("<",   "<").replaceAll(">",   ">").replaceAll("\n",   "<br/>");
     }
}

先看第一个文件echo.xhtml,其中action="echo",此处没有如JSF1.2中写一个表达式,这是新加入的一种导航方式,可以直接写文件的除后缀以外的名称,JSF2引擎会自动找到对应的文件,然后导航。另外看看escape="false"属性,这个是为了直接将内容中的标签以html方式显示,你可以调整本例中escape以及后台返回的outText的方法,看看前面的显示,这是非常有趣的。
好了,这个例子可以运行了,在页面中输入http://localhost:8080/TestJsf2.0/echo.xhtml就可以访问了。

二、     将输入值组件化:
现在真正将上述例子用自定义的复合组件改写一下,整个过程会非常简单,后台的bean都不用改写,只用改变页面就行。
我们看看自定义的组件echoInputText.xhtml,此页面需要放在WebRoot下的resources/echo/文件夹下。

echoInputText.xhtml:
<?xml   version="1.0"   encoding="gb2312"?>
<!DOCTYPE   html   PUBLIC   "-//W3C//DTD   XHTML   1.0   Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html   xmlns="http://www.w3.org/1999/xhtml"
                 xmlns:f="http://java.sun.com/jsf/core"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:composite="http://java.sun.com/jsf/composite">
         <!--   INTERFACE   -->
         <composite:interface>
             <composite:attribute   name="echo"/>
         </composite:interface>

         <!--   IMPLEMENTATION   -->                    
         <composite:implementation>
         <div   style="padding:20px;">
             <span>请输入响应文字:</span>
             <h:inputText   value="#{cc.attrs.echo.echoText}"></h:inputText>
         </div>
         </composite:implementation>
</html>

此文件将echo.xhtml中的
             <div   style="padding:20px;">
                 <span>请输入响应文字:</span>
                 <h:inputText   value="#{echo.echoText}"></h:inputText>
             </div>
提取出来,做成一个echoInputText组件,然后修改echo.xhtml为以下样子:

echo.xhtml:
<!DOCTYPE   html   PUBLIC   "-//W3C//DTD   XHTML   1.0   Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html   xmlns="http://www.w3.org/1999/xhtml"
             xmlns:h="http://java.sun.com/jsf/html"
             xmlns:f="http://java.sun.com/jsf/core"
             xmlns:echo="http://java.sun.com/jsf/composite/echo"
             xmlns:ui="http://java.sun.com/jsf/facelets">
     <h:head>
         <title>测试简单的复合组件</title>
         <meta   http-equiv="keywords"   content="jsf2.0,组件,ajax"   />
         <meta   http-equiv="description"   content="测试简单的复合组件."   />
         <meta   http-equiv="content-type"   content="text/html;   charset=UTF-8"   />
     </h:head>
     <body>
         <div   id="header"   style="padding:100px   0   20px   100px;font-size:22px;font-weight:bold;border-bottom:solid   1px   red">
             这个应声器的作者是:#{echo.encoder.author}。
         </div>
         <div>
         <h:form   id="form"   style="padding:20px   0   20px   100px">
             <echo:echoInputText   echo="#{echo}"></echo:echoInputText>
             <div   style="padding-left:50px">
                             <h:commandButton   id="post"   style="padding:3px;width:100px;"   value="提交响应"   action="echo"/>
             </div>
         </h:form>
         </div>
         <h:panelGroup   id="after">
         <div   style="padding:20px   0   0   100px">
         响应:<h:outputText   id="echo"   value="#{echo.outText}"   escape="false"></h:outputText>
         </div>
         </h:panelGroup>
     </body>
</html>

这两个文件修改后就可以运行了。

我们来分析一下自定义的echoInputText组件,先看看echo.xhtml文件有什么变化。看看xml命名空间中加入了xmlns:echo="http://java.sun.com/jsf/composite/echo",这个就是用来引用自定义的组件的,其中http://java.sun.com/jsf/composite/会默认指向到resources文件夹,后面直接跟资源的目录。resources文件夹是JSF2.0的一个默认资源放置文件夹,后面的echo就是指resources/echo/文件夹了。整个命名空间的意思就是将此文件夹命名为echo。再看看echo.xhtml文件中一处变化:
<echo:echoInputText   echo="#{echo}"></echo:echoInputText>
此段告诉我们直接采用了echo命名空间下的echoInputText组件,其中有一个属性为echo,指向的就是managed   bean:echo。

再看看echoInputText组件:
         <composite:interface>
             <composite:attribute   name="echo"/>
         </composite:interface>
这一段用来定义此组件接口,并且定义一个属性,属性名为echo。

         <composite:implementation>
         <div   style="padding:20px;">
             <span>请输入响应文字:</span>
             <h:inputText   value="#{cc.attrs.echo.echoText}"></h:inputText>
         </div>
         </composite:implementation>
这一段用来实现组件,其实中间的内容就是原先echo.xhtml文件中的输入组件,cc.attrs是JSF2.0组件定义中默认属性,可以用来引用接口中定义的属性。


最后,我们已经完成了一个简单的自定义符合组件,其中还用到了一下新的特性,大家可以多多查看JSF2.0的接口定义,去更多的了解。

你可能感兴趣的:(bean,xml,XHTML,JSF,sun)