pout 发表于http://www.leefn.com 时间2009-07-10 12:42
在本篇介绍中,我们开始接触JSF2.0纳为标准的最重要的特性之一,facelets组件模型,整个组件模型的特性是很多的,我在本系列中只能做简单的介绍,并试图用比较简单的例子为大家揭示JSF2.0带给我们独特而快捷的开发体验。
从本篇开始,我采用同一个例子,给大家依次揭示JSF2.0的组件与Ajax模型等重要内容。另外有任何问题,请在JSF2.0组中提出来,大家一起探讨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的接口定义,去更多的了解。
在下一篇中我们来一起看看JSF2.0组件中另外一个激动人心的改进,页面模版化。