自定义JSF组件

自定义JSF组件<o:p></o:p>

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

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

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. }

<o:p></o:p>

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

<o:p> </o:p>

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

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. }

<o:p></o:p>

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

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

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. }

<o:p></o:p>

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

<o:p></o:p>

<o:p></o:p>

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.03<!---->tlib-version>
  6. <jsp-version>1.2<!---->jsp-version>
  7. <short-name>dinnercn<!---->short-name>
  8. <uri>http://www.dinnercn.com/jsf/ <!---->uri>
  9. <tag>
  10. <name>clob<!---->name>
  11. <tag-class>
  12. dinner.view.jsf.uicomponent.OutputClobTag
  13. <!---->tag-class>
  14. <attribute>
  15. <name>value<!---->name>
  16. <!---->attribute>
  17. <!---->tag>
  18. <!---->taglib>

<o:p></o:p>

<name><o:p></o:p></name>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

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

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.Clob<!---->component-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.Clob<!---->component-family>
  15. <renderer-type>dinner.Clob<!---->renderer-type>
  16. <renderer-class>
  17. dinner.view.jsf.uicomponent.OutputClobRender
  18. <!---->renderer-class>
  19. <!---->renderer>
  20. <!---->render-kit>
  21. <!---->faces-config>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p></o:p>

<o:p> </o:p>

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

<o:p> </o:p>

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

<o:p></o:p>

你可能感兴趣的:(apache,sql,jsp,xml,JSF)