Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

UI development with JavaServer Faces

Contributing developerWorks author.

Summary:  This tutorial provides an overview of JavaServer Faces (JSF) and walks you through the basics for developing Web applications using the technology. With Java developer and consultant Jackwind Li Guojie as your guide, you will examine the JSF life cycle, input validation, event handling, page navigation, and internationalization -- all of which are illustrated through a sample application.

Date:  02 Sep 2003
Level:  Introductory PDF:  A4 and Letter (357 KB | 39 pages)Get Adobe® Reader®

Activity:  22645 views
Comments:  

Creating custom components

Creating custom components overview

JavaServer Faces technology offers a rich set of standard, reusable UI components that we can use to construct UIs for Web applications easily. Additionally, the flexible architecture of JSF allows us to create custom components.

In our sample application, we created a custom component to display e-mail addresses. The e-mail address output component enables the OS to invoke an e-mail client automatically when the user clicks the e-mail address. Also, this component will hide the e-mail address from Web bots, putting a halt to spam in the early stages.

E-mail address output component

Creating the component tag handler

Creating a component tag is very similar to creating a custom JSP tag. javax.faces.webapp.UIComponentTag is the base class for all JSF component tag handlers. Here is the tag handler class for our e-mail address output component:

/*
 * $Id: UIOutputEmailTag.java,v 1.1 2003/06/20 16:48:49 jack Exp $
 * 
 */
package net.jackwind.jsf;

import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentTag;

/**
 * @author 	JACK	(Jun 19, 2003)
 * @class 	UIOutputEmail
 */
public class UIOutputEmailTag extends UIComponentTag {

	private String valueRef;
	private String value;

	protected String getComponentType() {
		return "UIOutputEmail";
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public String getValueRef() {
		return valueRef;
	}

	public void setValueRef(String newValueRef) {
		valueRef = newValueRef;
	}

	public String getRendererType() {
		return null;
	}

	protected void overrideProperties(UIComponent component) {
		super.overrideProperties(component);
		UIOutputEmail email = (UIOutputEmail) component;

		if (value != null) {
			email.setValue(value);
		}
		
		if(email.getValueRef() == null && valueRef != null) {
			email.setValueRef(valueRef);
		}
			
	}

}

There are two abstract methods in UIComponentTag: getComponentType() and getRendererType(). The getComponentType() method returns the component type for the component that is bound to the tag. The other method, getRendererType(), selects the Renderer to be used for rendering the component. In the code above, getRendererType() returns null, which means that the component manages rendering itself without using external renderers. overrideProperties() is used to override properties of the component if the corresponding properties of this tag handler were explicitly set, and the corresponding attribute of the component has not been not set. The rest are typical JavaBeans methods that can be used to get and set element values.


Creating the tag library descriptor

The tag library descriptor (TLD) associated with the output_email tag is illustrated below:

<?xml version="1.0" ?>
<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
   <tlib-version>1.0</tlib-version>
   <jsp-version>1.2</jsp-version>
   <short-name>JSF Email Component by Jack Li Guojie.</short-name>
   <display-name>JSF Email Component by Jack Li Guojie.</display-name>
   <description>
   This library contains custom email component for JSF
   </description>

   <tag>
      <name>output_email</name>
      <tag-class>net.jackwind.jsf.UIOutputEmailTag</tag-class>
      <body-content>JSP</body-content>
      <description>JSF Email Component by Jack Li Guojie.
   </description>
      <attribute>
         <name>id</name>
         <required>false</required>
         <rtexprvalue>false</rtexprvalue>
      </attribute>
      <attribute>
      	<name>value</name>
      	<required>false</required>
      	<rtexprvalue>false</rtexprvalue>
      </attribute>
      <attribute>
      	<name>valueRef</name>
      	<required>false</required>
      	<rtexprvalue>false</rtexprvalue>
      </attribute>
   </tag>
</taglib>

This TLD is defined in the file WEB-INF/email-tag.tld. There are three attributes: id is used to set the ID for this component; the other two attributes are used to set the value -- the e-mail address. If the e-mail address is stored in a bean, then valueRef should point to the property of the bean. The value attribute can be set to a static e-mail address directly, like so:

<jack:output_email id="outemail" value="jack@jackwind.net" />


Building the custom component

A component class defines the state and behavior of a UI component. The state information includes the component's type, identifier, and local value. Some examples of behavior defined by component class are decoding (converting the request parameter and other information to the component's local value), encoding (converting a local value to some markup), or updating model objects.

We create the e-mail address output component by extending the javax.faces.component.UIOutput class.

/*
 * $Id: UIOutputEmail.java,v 1.1 2003/06/20 16:48:49 jack Exp $
 * 
 */
package net.jackwind.jsf;

import java.io.IOException;
import java.util.StringTokenizer;

import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

/**
 * @author 	JACK	(Jun 19, 2003)
 * @class 	UIOutputEmail
 */
public class UIOutputEmail extends UIOutput {
	private String host;
	private String user;
	
	private void parseEmail(String email) {
		StringTokenizer st = new StringTokenizer(email, "@");
		if (st.countTokens() != 2)
			throw new IllegalArgumentException(
				"Invalid email address: " + email);
		user = st.nextToken();
		host = st.nextToken();
	}
	
	// This method indicates whether this component renders itself
	// or delegates rendering to a renderer.
	public boolean getRendersSelf() { 
	   return true; 
	}
	
	// Called during the Render Response phase
	public void encodeEnd(FacesContext context) throws IOException {
		if(user == null || host == null) {
			try {
				parseEmail((String)currentValue(context));
			}catch(Exception e) {
				LogUtil.log(e);
			}
		}
		ResponseWriter writer = context.getResponseWriter();
		
		// Represent this component as HTML with JavaScripts
		writer.write("<script language='JavaScript'>\n");
		writer.write("function emailAddress(host, user) { \n");
		writer.write("document.write('<a href=\"mailto:');\n");
		writer.write("document.write(user + '@' + host);\n");
		writer.write("document.write('\">');\n");
		writer.write("document.write(user + '@' + host);\n");
		writer.write("document.write(\"</a>\");\n}\n\n");
		writer.write("emailAddress('" + host + "', '" + 
		  user + "');\n");
		writer.write("</script>\n");
	}

	protected String getComponentType() {
		return "output_email";
	}
}

Note that we override the encodeEnd() method to render the component into HTML markup. This method will be called during the Render Response phase of the JSF life cycle.


Registering the component

To register the component, we need to put a component entry into the application configuration file. Here is the code to register the e-mail address output component:

  <!-- ============== Custom components ========================= -->
  <component>
  	<component-type>UIOutputEmail</component-type>
  	<component-class>net.jackwind.jsf.UIOutputEmail</component-class>
  </component>


Using the custom component

We've now created and registered our custom component. It can be used in the same way as standard components. The code below displays an e-mail address that is stored in the bean (see the file thanks.jsp):

<%@ taglib uri="/WEB-INF/jsf-demo-jack.tld" prefix="jack" %>
...
<jack:output_email id="outemail" valueRef="subscriberBean.email" />

And here's the HTML output from this component:

<script language='JavaScript'>
function emailAddress(host, user) { 
document.write('<a href="mailto:');
document.write(user + '@' + host);
document.write('">');
document.write(user + '@' + host);
document.write("</a>");
}

emailAddress('jackwind.net', 'jack');
</script>

9 of 13 | Previous | Next

Comments



Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=131877
TutorialTitle=UI development with JavaServer Faces
publish-date=09022003
author1-email=
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).