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>/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="/custom-taglib">

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

Using Custom JSF 2.2 tags

If you are planning to use JSF 2.2 then creating custom tags is even simpler! In JSF 2.2 declaring the tag into an XML file is not required anymore an the tag declaration can be done via the component’s annotation. For this the @FacesComponent annotation introduces 3 new attributes:

  • createTag : If set to true the component will be directly useable via a tag on a Facelet.
  • tagName:  Optional explicit name for the tag. If omitted, the class’ simple name with the first character in lowercase will be used.
  • namespace: Optional explicit namespace for the tag. If omitted the namespace http://java.sun.com/jsf/component will be used.

Here’s your custom tag based on the JSF 2.2 implementation

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", createTag=true)
public class TranslatorComponent extends UIComponentBase {
   . . . .
}

And here’s how to reference it from within your XHTML page:

<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="/custom-taglib">

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

Download the code from this article.


Recommended Articles

Create JSF Custom Tags Using XHTML in Enterprise Java Applications

Learn how to create reusable forms and settings using custom JSF tags based on an XHTML page. #EnterpriseJava #JSF #CloudNative

Create a Custom JSF Converter for User Object - Jakarta Server Faces (JSF) Tutorial

Learn how to create a custom JSF converter for User objects in Java applications using WildFly 31 and Java 21. #Java #Middleware #CloudNative

JSF Data Validation Tutorial: Enhance Your Applications with JSF 2.0

Learn how to leverage JSF validation for cleaner, more efficient applications. #Java #Middleware #CloudNative

Calling Methods with Parameters in JSF: A Powerful Approach

Learn how to pass parameters to methods in JSF using method expressions and dynamic attributes. Get started with a simple example and take your JSF skills to the next level.