论坛首页 Java版 Tomcat

自定义JSF组件

浏览 3353 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-03-27 关键字: jsf 自定义组件

自定义JSF组件

个人感觉,写一个jsf的组件比jsp的标签要复杂得多,因为jsp的标签,只有生成html代码的功能,jsf组件还有如增加事件,增加效验,返回用户反馈的值。等等!一个组件一般是分三部分,扩展UIComponent、定义标签、定义渲染器、。现在我就以一个最简单的例子,制作一个输出CLOB的组件来说明一下组件的建立的基本步骤

第一步:扩展UIComponent,他有一个实现类UIComponentBase,一般最基础的组件就是从这个类里扩展而来的,如果你在客户端显示Bean中的字段,你需要实现ValueHolder接口字段,如UIOutput组件;如果有返回值的话,还需要你实现EditableValueHolder接口,如UIInput组件。一般情况下,如果没有返回值就可以继承UIOutput组件,如果有返回值实现UIInput组件。这样,我们只要这样就可用以下代码就可以实现一个组件部分的编写

java 代码
  1. package dinner.view.jsf.uicomponent;
  2. import javax.faces.component.UIOutput;
  3. public class OutputClobComponent extends UIOutput{
  4. public static final String COMPONENT_TYPE = "dinner.Clob";
  5. public static final String COMPONENT_FAMILY = "dinner.Clob";
  6. private static final String DEFAULT_RENDERER_TYPE = "dinner.Clob";
  7. public OutputClobComponent () {
  8. setRendererType(DEFAULT_RENDERER_TYPE);
  9. }
  10. @Override
  11. public String getFamily(){
  12. return COMPONENT_FAMILY;
  13. }
  14. }

在构函数中的setRendererType(COMPONENT_FAMILY) getFamily 是指定用来生成HTML代码的渲染器,渲染器需要在faces-config.xml中进行配制,关于配制,在最后一步我会进行说明的。

第二步,定义渲染器。渲染器我们需要从Renderer类中继承,不过我们一般情况下会继承HtmlRenderer这个类,我们可以覆盖decode encodeBegin encodeChildren encodeEnd 来生成HTML,在这里,和自定义jsp标签的几个方法十分的相似,所以就不深入的说下去了,我们看一下例子。

java 代码
  1. package dinner.view.jsf.uicomponent;
  2. import java.io.IOException;
  3. import java.sql.Clob;
  4. import java.sql.SQLException;
  5. import javax.faces.component.UIComponent;
  6. import javax.faces.context.FacesContext;
  7. import javax.faces.context.ResponseWriter;
  8. import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
  9. import org.apache.myfaces.shared_impl.renderkit.html.HtmlRenderer;
  10. public class OutputClobRender extends HtmlRenderer{
  11. @Override
  12. public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
  13. RendererUtils.checkParamValidity(context, component, null);
  14. Clob clob = (Clob)RendererUtils.getObjectValue(component);
  15. ResponseWriter writer = context.getResponseWriter();
  16. String strValue = "";
  17. try {
  18. strValue = clob.getSubString(1,(int)clob.length());
  19. } catch (SQLException e) {
  20. e.printStackTrace();
  21. }
  22. writer.write(strValue);
  23. }
  24. }

因为例子很简单,所以只覆盖了encodeEnd方法。在这里,我们用到了RendererUtils类,在这个类里有很多的静态方法,如RendererUtils.getObjectValue是为了得到以这个控件绑定的字段。

第三步,定义标签,在这一步中我们需要继承UIComponentTag这个类,但在实际应用中,我们可以继承他的子类,比如在例子中我们就继承HtmlOutputTextTagBase。在标签类中,我们必须要覆盖getComponentType方法和getRendererType,来指定这个标签属于哪个组件和渲染器,这两个属性的返回值都应和配制文件指定的值相同。

java 代码
  1. package dinner.view.jsf.uicomponent;
  2. import org.apache.myfaces.shared_impl.taglib.html.HtmlOutputTextTagBase;
  3. public class OutputClobTag extends HtmlOutputTextTagBase{
  4. @Override
  5. public String getComponentType() {
  6. return OutputClobComponent.COMPONENT_TYPE;
  7. }
  8. @Override
  9. public String getRendererType() {
  10. return "dinner.Clob";
  11. }
  12. }

在建立后tag类后,我们还需要做建一个tag文件,这样才能使用这个组件,在这里,和jsp自定义标签是一样的,所以也不再详述了,以下是代码

xml 代码
  1. xml version="1.0" encoding="ISO-8859-1" ?>
  2. PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  3. "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
  4. <taglib>
  5. <tlib-version>0.03tlib-version>
  6. <jsp-version>1.2jsp-version>
  7. <short-name>dinnercnshort-name>
  8. <uri>http://www.dinnercn.com/jsf/ uri>
  9. <tag>
  10. <name>clobname>
  11. <tag-class>
  12. dinner.view.jsf.uicomponent.OutputClobTag
  13. tag-class>
  14. <attribute>
  15. <name>valuename>
  16. attribute>
  17. tag>
  18. taglib>

第四步,配制文件,我们写好了所有的代码后,就可以进行配制了,配制文件如下

xml 代码
  1. xml version="1.0"?>
  2. "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
  3. <faces-config>
  4. <component>
  5. <description>组件的配制description>
  6. <component-type>dinner.Clobcomponent-type>
  7. <component-class>
  8. dinner.view.jsf.uicomponent.OutputClobComponent
  9. component-class>
  10. component>
  11. <render-kit>
  12. <description>渲染器的配制description>
  13. <renderer>
  14. <component-family>dinner.Clobcomponent-family>
  15. <renderer-type>dinner.Clobrenderer-type>
  16. <renderer-class>
  17. dinner.view.jsf.uicomponent.OutputClobRender
  18. renderer-class>
  19. renderer>
  20. render-kit>
  21. faces-config>

在这里,需要注意的事,组件和渲染器的component-familyrenderer-typecomponent-type必须要以代码中写的返回值是一样的。

到这里一个简单的组件就完成的,所以如果选择好继承类的话,写一个组件还是挺简单的。

   
最后更新时间:2007-03-27
jsf没用过,这东西到底好不好用?
   
0 请登录后投票
最后更新时间:2007-03-28
andyandyandy 写道
jsf没用过,这东西到底好不好用?
好用不好用,不是别人说的算,自己用过才知道。
   
0 请登录后投票
最后更新时间:2007-04-16
这几天刚好在看jsf的使用
感觉比用struts来写view视图比较易懂些!!
不过楼主说的标签开发有难度确实不假!!
比单单写jsp标签难多啦!!

jsf使用组件事件来操作view层,俺大大支持,但要用到一个生硬的标签,个人感觉学JAVA越学越累!!

感觉typetry这个比jsf的中庸态度来得更好!!至少俺不用去学自定义标签
   
0 请登录后投票
论坛首页 Java版 Tomcat

跳转论坛:
JavaEye推荐