http://guoshiguan.javaeye.com/blog/65794 个人感觉,写一个jsf的组件比jsp的标签要复杂得多,因为jsp的标签,只有生成html代码的功能,jsf组件还有如增加事件,增加效验,返回用户反馈的值。等等!一个组件一般是分三部分,扩展UIComponent、定义标签、定义渲染器、。现在我就以一个最简单的例子,制作一个输出CLOB的组件来说明一下组件的建立的基本步骤 第一步:扩展UIComponent,他有一个实现类UIComponentBase,一般最基础的组件就是从这个类里扩展而来的,如果你在客户端显示Bean中的字段,你需要实现ValueHolder接口字段,如UIOutput组件;如果有返回值的话,还需要你实现EditableValueHolder接口,如UIInput组件。一般情况下,如果没有返回值就可以继承UIOutput组件,如果有返回值实现UIInput组件。这样,我们只要这样就可用以下代码就可以实现一个组件部分的编写 package dinner.view.jsf.uicomponent; import javax.faces.component.UIOutput; public class OutputClobComponent extends UIOutput{ public static final String COMPONENT_TYPE = "dinner.Clob"; public static final String COMPONENT_FAMILY = "dinner.Clob"; private static final String DEFAULT_RENDERER_TYPE = "dinner.Clob"; public OutputClobComponent () { setRendererType(DEFAULT_RENDERER_TYPE); } @Override public String getFamily(){ return COMPONENT_FAMILY; } } 在构函数中的setRendererType(COMPONENT_FAMILY) 和getFamily 是指定用来生成HTML代码的渲染器,渲染器需要在faces-config.xml中进行配制,关于配制,在最后一步我会进行说明的。 第二步,定义渲染器。渲染器我们需要从Renderer类中继承,不过我们一般情况下会继承HtmlRenderer这个类,我们可以覆盖decode encodeBegin encodeChildren encodeEnd 来生成HTML,在这里,和自定义jsp标签的几个方法十分的相似,所以就不深入的说下去了,我们看一下例子。 package dinner.view.jsf.uicomponent; import java.io.IOException; import java.sql.Clob; import java.sql.SQLException; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import org.apache.myfaces.shared_impl.renderkit.RendererUtils; import org.apache.myfaces.shared_impl.renderkit.html.HtmlRenderer; public class OutputClobRender extends HtmlRenderer{ @Override public void encodeEnd(FacesContext context, UIComponent component) throws IOException { RendererUtils.checkParamValidity(context, component, null); Clob clob = (Clob)RendererUtils.getObjectValue(component); ResponseWriter writer = context.getResponseWriter(); String strValue = ""; try { strValue = clob.getSubString(1,(int)clob.length()); } catch (SQLException e) { e.printStackTrace(); } writer.write(strValue); } } 因为例子很简单,所以只覆盖了encodeEnd方法。在这里,我们用到了RendererUtils类,在这个类里有很多的静态方法,如RendererUtils.getObjectValue是为了得到以这个控件绑定的字段。 第三步,定义标签,在这一步中我们需要继承UIComponentTag这个类,但在实际应用中,我们可以继承他的子类,比如在例子中我们就继承HtmlOutputTextTagBase。在标签类中,我们必须要覆盖getComponentType方法和getRendererType,来指定这个标签属于哪个组件和渲染器,这两个属性的返回值都应和配制文件指定的值相同。 package dinner.view.jsf.uicomponent; import org.apache.myfaces.shared_impl.taglib.html.HtmlOutputTextTagBase; public class OutputClobTag extends HtmlOutputTextTagBase{ @Override public String getComponentType() { return OutputClobComponent.COMPONENT_TYPE; } @Override public String getRendererType() { return "dinner.Clob"; } } 在建立后tag类后,我们还需要做建一个tag文件,这样才能使用这个组件,在这里,和jsp自定义标签是一样的,所以也不再详述了,以下是代码 xml version="1.0" encoding="ISO-8859-1" ?> PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
0.03
tlib-version>
1.2
jsp-version>
dinnercn
short-name>
http://www.dinnercn.com/jsf/
uri>
clob
name>
dinner.view.jsf.uicomponent.OutputClobTag
tag-class>
value
name>
attribute>
tag>
taglib> 第四步,配制文件,我们写好了所有的代码后,就可以进行配制了,配制文件如下 xml version="1.0"?> "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
组件的配制
description>
dinner.Clob
component-type>
dinner.view.jsf.uicomponent.OutputClobComponent
component-class>
component>
渲染器的配制
description>
dinner.Clob
component-family>
dinner.Clob
renderer-type>
dinner.view.jsf.uicomponent.OutputClobRender
renderer-class>
renderer>
render-kit>
faces-config> 在这里,需要注意的事,组件和渲染器的component-family,renderer-type,component-type必须要以代码中写的返回值是一样的。
自定义JSF组件
最新推荐文章于 2021-06-17 16:46:32 发布