23
Sep
10

JSF Custom Components Hello World


This page describes how to write a JSF Custom component to print “Hello World” to the page.

This is a demonstration on how to create JSF custom tags using the Sun’s JSF Reference Implementation. This page will lay a solid foundation on how to write custom components to wrap any library or tool kits available for web development into standard JSF components.

This is crazy but these are the steps involved in creating a new JSF Component.

New JSF Custom Component Checklist:

  1. Component Class – This is the Java class that represents the core logic of the component. This class can be coded to render itself or use the help of a the “Renderer” class.
  2. Component Renderer – Responsible for rendering the component on the page.
  3. Tag Class – This is class brings the “custom tag” concept onto the table. Custom Tag libraries were introduced with the JSP 1.1 specification back in December 1999. Today the JSF specification builds upon the custom tag library concept.
  4. Tag Library Descriptor – XML file necessary for the custom tag.
  5. Faces Context – XML file necessary for the custom component.

Requirements

  • Maven 2 or later
  • JSF 1.2 or above
  • Java 5 or later

Start a new Maven Project

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp

For the group id enter: org.extjsf
For the artifactId enter: jsfCustom

Answer the rest of the questions using defaults [Hit Enter].

cd to the project’s folder

Next we create the src/main/java folder since this is not done for us using the archetype.

on unix you type:

cd jsfCustom
mkdir -p src/main/java

Project Configuration File

Modify the pom.xml file. It should look like this…

vi pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.extjsf</groupId>
    <artifactId>extJSF</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>jsfTestWeb Maven Webapp</name>
    <url>http://extjsf.org</url>
    <dependencies>
        <dependency>
            <groupId>javax.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>1.2_02</version>
            <scope>compile</scope> <!--use compile scope for testing with jetty-->
        </dependency>
        <dependency>
            <groupId>javax.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>1.2-b19</version>
            <scope>compile</scope> <!--use compile scope for testing with jetty-->
        </dependency>
        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
			<artifactId>geronimo-jsp_2.1_spec</artifactId>
			<version>1.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-servlet_2.5_spec</artifactId>
            <version>1.2</version>
            <scope>provided</scope>
        </dependency>
		<dependency>
		    <groupId>javax.el</groupId>
		    <artifactId>el-api</artifactId>
		    <version>1.0</version>
		    <scope>provided</scope>
		</dependency>        
    </dependencies>
    <build>
        <finalName>extJSFWeb</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
				<version>7.0.0.v20091005</version>
                <configuration>
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <configuration>
                    <wtpapplicationxml>true</wtpapplicationxml>
                    <wtpversion>1.5</wtpversion>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                    <classpathContainers>
                        <classpathContainer>org.eclipse.jst.j2ee.internal.web.container</classpathContainer>
                        <classpathContainer>org.eclipse.jst.j2ee.internal.module.container</classpathContainer>
                    </classpathContainers>
                    <additionalProjectFacets>
                        <jst.web>2.5</jst.web>
                        <jst.jsf>1.2</jst.jsf>
                    </additionalProjectFacets>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

web.xml

This is boiler plate code. There are no references to the custom components.

We will start from a fresh web.xml file so delete the one that is there.
rm src/main/webapp/WEB-INF/web.xml

Edit the file using a text editor.
vi src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.jsf</welcome-file>
  </welcome-file-list>

</web-app>

Create the Component Class

As mentioned above this is the main class that represents the custom component. It can either render itself or have another class assigned to do the work of rendering. In this case all we are defining is the component family. This is the package we will use to place all the components in.

Create the directory if it does not exist
mkdir -p src/main/java/org/extjsf/component/helloworld

Edit the file using a text editor.
vi src/main/java/org/extjsf/component/helloworld/HtmlHelloWorld.java

package org.extjsf.component.helloworld;

import javax.faces.component.UIComponentBase;

public class HtmlHelloWorld extends UIComponentBase {
	public static final String COMPONENT_FAMILY = "org.extjsf.component";

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}
}

Create the Component Renderer

This is where the actual rendering of the hello world message is done.
Edit the file using a text editor.
vi src/main/java/org/extjsf/component/helloworld/HelloWorldRenderer.java

package org.extjsf.component.helloworld;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

public class HelloWorldRenderer extends Renderer {
    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        writer.startElement("div", component);
        writer.writeAttribute("style", "color: red", null);
        writer.writeText("HelloWorld! from renderer.", null);
        writer.endElement("div");
    }
}

Create the Tag Class

This is the custom tag class that will allow the JSP to communicate with the JSF component. You can consider this to be a “hook” into the Java Server Pages API. Allows the JSP page developer to pass “parameters” as tag attributes to the JSF custom component.

The Custom Tag class “componentType” is used to lookup the JSF Component class using the faces-context.xml.
Edit the file using a text editor.
vi src/main/java/org/extjsf/component/helloworld/HtmlHelloWorldTag.java

package org.extjsf.component.helloworld;

import javax.faces.webapp.UIComponentTag;

public class HtmlHelloWorldTag extends UIComponentTag {
    @Override
    public String getComponentType() {
        return "HtmlHelloWorld";
    }
    public String getRendererType() {
        return "org.extjsf.component.HelloWorldRenderer";
    }
}

Create the Tag Library Descriptor

Edit the file using a text editor.
vi src/main/webapp/WEB-INF/htmlHelloWorld.tld

<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-
jsptaglibrary_2_0.xsd"
	version="2.0">
<tlib-version>1.0</tlib-version>
<uri>http://extjsf.org/components</uri>

<tag>
	<description>Hello World Tag</description>
	<name>helloworld</name>
	<tag-class>org.extjsf.component.helloworld.HtmlHelloWorldTag</tag-class>
</tag>
</taglib>

Modify the faces-config.xml

Edit the file using a text editor.
vi src/main/webapp/WEB-INF/faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config 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-facesconfig_1_2.xsd"
              version="1.2">

<component>
	<component-type>HtmlHelloWorld</component-type>
	<component-class>org.extjsf.component.helloworld.HtmlHelloWorld</component-class>
</component>
<render-kit>
	<renderer>
		<component-family>org.extjsf.component</component-family>
		<renderer-type>org.extjsf.component.HelloWorldRenderer</renderer-type>
		<renderer-class>org.extjsf.component.helloworld.HelloWorldRenderer</renderer-class>
	</renderer>
</render-kit>

</faces-config>

Create the JSP Page

Create the examples directory
mkdir -p src/main/webapp/examples

Edit the file using a text editor.
vi src/main/webapp/examples/helloWorld.jsp

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<%@ taglib prefix="e" uri="http://extjsf.org/components" %>

<f:view>
    <html>
    <head>
        <title>Hello World JSF Example</title>
</head>
    <body>
<e:helloworld/>
    </body>
    </html>
</f:view>

The following is how all these files are related:

  1. Servlet Container encounters a <e:helloworld/> tag and checks the tag library described by the “http://extjsf.org/components&#8221; tag library xml file.
  2. The tag library xml file indicates that the “org.extjsf.component.helloworld.HtmlHelloWorldTag” is responsible for handling the custom tag.
  3. The System inspects the HtmlHelloWorldTag and gets the component Type and RendererType.
  4. The System inspects the faces-config.xml reads that “HtmlHelloWorld” component type is handled by the “HtmlHelloWorld” component class, and rendered by the “HelloWorldRenderer”.
  5. The family that is specified in the component class is used to make a determination on what renderer family to use.

Run the application

Drop to the command line and navigate to the project’s base directory (location of the pom.xml file).

Execute the following command to test the web application using Jetty servlet engine.

mvn jetty:run

Navigate to: http://localhost:8080/examples/helloWorld.jsf

Next steps

Classic Form Components:

INPUT
	text
	password
	checkbox
	image
	hidden
	file
LABEL

Buttons
-------
http://developer.yahoo.com/yui/button/
INPUT
	radio
	submit 
	reset
	button
BUTTON
SELECT

TEXTAREA
--------
http://developer.yahoo.com/yui/editor/

PRIMEFACES
----------

Mobile Components
-----------------
Pages &amp; Dialogs
Toolbars
	Header
	Footer
	Nav Bars
	Persistant Footer Nav
	
Buttons
	Inline Buttons (more narrow)
	Grouped Buttons
Layout
	Column Grids
	Collapsible Content
	
Form Elements
	Text
	Text Area
	Search Input
	Flip Switch
	Slider
	checkbox
	Radio
	Select

Lists
	Nested List
	Numbered List
	Split Button List
	Formatted Content

Advanced functionality:
Making AJAX requests for JSON data, Sorting Hiding of grid columns, grouping, row expanding, type ahead combo boxes, validation, Editor grid panel, saving preferences in browser cookies and in the database, live search functionality.

That’s all for now.

More to come.

Advertisements

2 Responses to “JSF Custom Components Hello World”


  1. 1 Vikas
    May 29, 2011 at 2:42 am

    Good stuff. Thanks


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 77 other followers

September 2010
S M T W T F S
« Aug   Oct »
 1234
567891011
12131415161718
19202122232425
2627282930  

Blog Stats

  • 847,163 hits

%d bloggers like this: