I am trying to develop custom control in JSF 1.2 (using facelets).
I followed steps from different tutorials (defining .tld, taglib.xml, registered component in faces-config.xml and implementing UIComponent (c开发者_开发百科omponent renders itself) and UIComponentELTag classes) and my component is rendered, I have value bound to it, but attributes I defined for that tag are ignored. I logged various methods in Tag class and noticed that none of the methods is ever called.
What am I missing? Is there a reason Tag handler class is never invoked?
Thanks in advance.
My taglib.xml file is:
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>dynamissoft.com/entities/ui</namespace>
<tag>
<tag-name>legalEntityView</tag-name>
<component>
<component-type>rs.bozic.wastemanager.LegalEntityView</component-type>
</component>
</tag>
</facelet-taglib>
Have you tried creating a custom component using facelets (xml only). That's the most easy way, using facelets, usually, the different java classes aren't needed anymore.
Very rough overview:
- Create facelet xml file (like myComponent.xhtml)
- Register in the facelet inside a taglib (which in turn should be defined in the web.xml)
- Optionally, create some support beans in Java
You can pass values/beans to your component using normal tag paramets:
Using the component
Inside the component
Param1 is just printed: #{myParam2} Param2 used as value for table ...
There are excellent tutorials on Google, like the one from IBM.
If possible, consider using JSF 2.0. Facelets are integrated, and you have more flexibility to create your custom components. I created a blog posting a while ago on that: http://blog.whitehorses.nl/2010/02/08/jsf-2-0/ (or Google yourself)
Just to expand Gerbrand's answer a bit, here's a procedure for a simple Facelets-compatible component. It renders a span
tag that wraps a text specified via component's text
attribute.
First create the component class (in our case it's just a flavour of
UIOutput
):package sample.mytag; import java.io.IOException; import javax.faces.component.UIOutput; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; public class SpanComponent extends UIOutput{ private String text; @Override public Object saveState(FacesContext context) { Object values[] = new Object[2]; values[0] = super.saveState(context); values[1] = target; return ((Object) (values)); } @Override public void restoreState(FacesContext context, Object state) { Object values[] = (Object[])state; super.restoreState(context, values[0]); target = (String)values[1]; } public String getText() { return text; } public void setText(String text) { this.text = text; } @Override public void encodeBegin(FacesContext context) throws IOException { ResponseWriter writer=context.getResponseWriter(); writer.startElement("span", component); writer.writeAttribute("id", id, null); writer.writeText(text, null); writer.endElement("span"); writer.flush(); } @Override public String getFamily(){ return "myTag.component"; } @Override public void encodeEnd(FacesContext context) throws IOException { return; } @Override public void decode(FacesContext context) { return; } }
Next, we need a taglib XML file, let's call it
mytag.taglib.xml
and put it insideWEB-INF
dir.<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "WEB-INF/facelet-taglib_1_0.dtd"> <facelet-taglib> <namespace>http://sample.tag/mytags</namespace> <tag> <tag-name>myspan</tag-name> <component> <component-type>myTag.component</component-type> </component> </tag> </facelet-taglib>
Note that:
.taglib.xml
suffix is mandatory<component-type>
should have the same value that is returned by component'sgetFamily()
method- you can
replace
WEB-INF/facelet-taglib_1_0.dtd
withhttp://java.sun.com/dtd/facelet-taglib_1_0.dtd
It's time to modify web.xml and faces-config.xml.
Former should be modified with
<context-param> <param-name>facelets.LIBRARIES</param-name> <param-value>/WEB-INF/mytag.taglib.xml</param-value> </context-param>
faces-config.xml should get
<component> <component-type>myTag.component</component-type> <component-class>sample.mytag.LabelComponent</component-class> </component>
We're good to go!
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:sample="http://sample.tag/mytag"> <sample:myspan text="I'm inside a span!"/> </ui:composition>
精彩评论