JSF custom tags using Java classes

This is the second tutorial about creating JSF custom tags. In this one we will show how to create Java based JSF custom tags.

Creating a custom Java based JSF tag in the early JSF 1.2 specification required pretty a lot of work and several configuration files to be handled. We will now show how simpler is now with the JSF 2.1 specifications and how (even!) simpler is with the JSF 2.2 specifications.
Creating a JSF 2.1 compliant (Java based) custom tag requires just three simple steps:


Step # 1 Define your Java class extending the UIComponentBase which renders your tag:

package com.sample;

import java.io.IOException;
import java.util.Hashtable;

import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

@FacesComponent(value = "dictionary")

public class TranslatorComponent extends UIComponentBase {

    Hashtable dictionary = new Hashtable();

    @Override

    public String getFamily() {        

        return "translatorComponent";

    }

    public TranslatorComponent() {
        dictionary.put("dog", "cane");
        dictionary.put("cat", "gatto");
        dictionary.put("mouse", "topo");
    }

    @Override

    public void encodeBegin(FacesContext context) throws IOException {
      
        String value = (String) getAttributes().get("value");

        if (value != null) {        

            ResponseWriter writer = context.getResponseWriter();
            Object translation = dictionary.get(value);
            if (translation == null) {
                  writer.write("Sorry word not found!");
            }
            else {
                  writer.write((String)translation);
            }

        }

    }

}

The above tag can be used to translate some words from one dictionary into another (in our example some words from English to Italian).

Two things to notice:
The @FacesComponent(value = "dictionary") which can be used to declare the Java class as Faces Component (instead of declaring it into a TLD configuration file)
Next, Since our component only displays a message, and the tag doesn't contain any children, we only need to override the encodeBegin method, which renders the tag.

For advanced components, which have a body, we should have three overridden methods:

  • encodeBegin: This starts the element for the root component
  • encodeChildren: This would cause all of the children to be encoded
  • encodeEnd: This closes the element

Step #2 Define your tag within a tag lib file:
Add the following custom.taglib.xml to your WEB-INF folder:

<facelet-taglib 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-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://www.mastertheboss.com/custom-taglib</namespace>
    <tag>
        <tag-name>mydictionary</tag-name>
        <component>
            <component-type>dictionary</component-type>
        </component>
    </tag>
     
</facelet-taglib>

As you can see, we are referencing the source XHTML contained in tags/form.xhtml and associating it with the "form" tag name.

Step #3 Add a reference to your tag lib in web.xml

 <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/custom.taglib.xml</param-value>
 </context-param>

(Please note that the older facelets.LIBRARIES property has been deprecated and might not work in some Java EE servers. So use the above javax.faces.FACELETS_LIBRARIES for JSF 2 compliant servers)
 Now that everything is in place you can just reference your tag within your XHTML pages as shown:
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ct="http://www.mastertheboss.com/custom-taglib">

<h:body>           
  <h:form>
         Translation: Dog is <ct:mydictionary value="dog" />
  </h:form>
</h:body>
 
</html>

Follow us on Twitter