完整的教材: html
上一节教程中定义的组件,使用组件自己的encodeBegin方法输出了html代码,更好的方法是使用Render类来输出,为何要单独使用另一个类来输出html代码呢?这跟mvc设计有关,这里的组件(model)保存了java的各类属性,而输出的视图能够是html、json、xml等等,因此须要使用Render类在model与view之间进行转换,一般咱们只须要实现html的render就好了。 java
咱们仍是拿第1个教材的HelloWorld源代码进行改造 。 web
开发环境:
json
- Windows 7
- IntelliJ IDEA 12.1.2
- jboss-6.1.0.Final
- JSF 1.2
下面的5个步骤是这个组件的重构过程: mvc
一、 定义组件UIHelloWorld,记住JSF的组件必须继承javax.faces.component.UIComponent或者它的子类。这里UIHelloWorld只是输出一句话,继承javax.faces.component.UIOutput最省事了,与上一节相比,这里去掉了encodeBegin方法,新增了getFamily方法。 app
public class UIHelloWorld extends UIOutput { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String getFamily() { return "com.regaltec.faces.HelloWorld"; } }
二、新建HelloWorldRender类,这个类继承javax.faces.render.Renderer类,需实现其中的encodeBegin、encodeEnd和decode方法,分别用来用来转换HTML和接受HTML值,这里只覆盖了encodeBegin方法。 ide
public class HelloWorldRender extends Renderer { @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { UIHelloWorld helloWorld = (UIHelloWorld) component; if (StringUtils.isNotBlank(helloWorld.getName())) { ResponseWriter writer = context.getResponseWriter(); writer.write("<div>"); writer.write(String.format("你好,%s! ", helloWorld.getName())); writer.write("</div>"); } } }
三、上面新建的Render类也必须在faces-config.xml里声明。 ui
<?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> <render-kit> <renderer> <component-family>com.regaltec.faces.HelloWorld</component-family> <renderer-type>com.regaltec.faces.render.HelloWorld</renderer-type> <renderer-class>com.regaltec.faces.renderkit.html.HelloWorldRender</renderer-class> </renderer> </render-kit> <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-family、renderer-type的命名规则能够事先规划好。 this
四、修改uicomponent.taglib.xml配置,新增renderer-type节点。 spa
<?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> <renderer-type>com.regaltec.faces.render.HelloWorld</renderer-type> </component> </tag> </facelet-taglib>
五、根据component-type、component-family、renderer-type这3个组合,能够肯定使用那一个Render类做视图的渲染。页面的无需修改,如下是helloWorld.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: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 id="welcome" name="世界" /> </body> </f:view> </html>
通过上面的改造后,Component类与Render类各守其职,并对多视图渲染提供了良好的扩展。
下一节我将重构代码,将这个name属性绑定到变量里,毕竟在项目开发中,大部份都是使用变量(表达式)。
以上代码在jboss-6.1.0.Final调试经过,感谢百度云网盘提供源码下载。