完整的教材:
公司决策层选择了JSF做页面,WEB开发人员不容易呀,一个页面动不动就几千行,如果一个新人加入团队,估计都看晕了。我今天要写的课程,就是跟简化页面代码有关系了。自定义组件不但可以复用代码,还能让页面的代码更简洁。自定义JSF组件与JSP标签不是一回事,这里我做一个HelloWolrd的示例,这个示例是循次渐进的演进,不只是一个简单的Hello World,不过看这课程的同学需要有JSF基础。
用过JSF的同学都知道,JSF的视图可以选择JSP或Facelets技术,而绝大部份人好像对Facelets情有独钟,我们公司也不例外用了Facelets。所以我们就从做一个支持Facelets组件开始。
这个组件组件很简单,就是根据name属性输出一句话,如下面这行代码输出为:你好,世界!
<ida:helloWorld name="世界" />
开发环境:
- Windows 7
- IntelliJ IDEA 12.1.2
- jboss-6.1.0.Final
- JSF 1.2
下面的步骤是实现这个组件的过程:
1、 首先当然是定义一个组件UIHelloWorld,记住JSF的组件必须继承javax.faces.component.UIComponent或者它的子类。这里UIHelloWorld只是输出一句话,继承javax.faces.component.UIOutput最省事了。
public class UIHelloWorld extends UIOutput {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.write("<div>");
if (StringUtils.isNotBlank(this.name)) {
writer.write(String.format("你好,%s!" + this.name));
}
writer.write("</div>");
}
}
HelloWorld组件只定义了一个属性name,并且覆盖了父类的encodeBegin方法,这个方法很简单,就是网页上输出一段文字。
2、在faces-config.xml里声明HelloWorld组件。
<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" version="1.2">
<component>
<component-type>com.regaltec.faces.HelloWorld</component-type>
<component-class>com.regaltec.faces.component.UIHelloWorld</component-class>
</component>
<application>
<locale-config>
<default-locale>zh_CN</default-locale>
<supported-locale>en_US</supported-locale>
</locale-config>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
component-type是组件的一个类型、名称之类的,可以根据个人喜好命名。
3、要在网页上使用这个组件,还必须要对这个组件作标签声明。标签的声明在uicomponent.taglib.xml这个文件中,这个文件一般以taglib.xml结尾,放在WEB-INF目录或者子目录下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.regaltec.com/ida40</namespace>
<tag>
<tag-name>helloWorld</tag-name>
<component>
<component-type>com.regaltec.faces.HelloWorld</component-type>
</component>
</tag>
</facelet-taglib>
namespace在写网页的时候会使用,而component-type这项与faces-config.xml的定义的必须要一致。
4、但是Application Server还不能识别我们自定义的组件,需要告诉Application Server自定义的标签在那里,这个步骤也简单,只要打开web.xml,加上下面3行代码。
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/uicomponent.taglib.xml</param-value>
</context-param>
5、经过上面4个步骤,我们已完成了HelloWorld组件的全部工作了,现在我写一个页面使用这个组件。
<!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:ida="http://www.regaltec.com/ida40" >
<f:view>
<head>
<title>Hello World</title>
</head>
<body>
<ida:helloWorld name="World" />
</body>
</f:view>
</html>
大家可以留意到,只要引入我们在uicomponent.taglib.xml的命名空间,就可以用ida:helloWorld来引用组件了。
下一节,我将使用Render类改造这个例子。Renderer类是JSF组件开发中一个较重要的类,该类主要功能是在Java和HTML之间的转换,在响应阶段将Java组件的属性转换为HTML代码,在接受请求阶段将HTML Request中传来的资料转换为Java组件的属性。
以上代码在jboss-6.1.0.Final调试通过,感谢百度云网盘提供源代码下载。
来源:oschina
链接:https://my.oschina.net/u/937910/blog/131994