Easy steps to create custom tags in JSP example code & tutorial.

Writing too much java code in JSP itself may not be a good practice because it makes the code too complex and maintenance becomes more difficult. So it is always better to keep Java code out of JSP pages (i.e separating business logic from presentation ) , which makes the jsp pages easier to maintain. There are lot more technologies to separate presentation and business logic. Like JavaBeans , custom tags also provide a mechanism for the separation

Advantages using Tags:

-Allows separation of presentation and business logic, allowing page designers to work on presentation while developers to code .

-Allows easy reuse of Java code.

-You can build and pack a custom tag library with useful functions and provide it to the end-user.

– Maintenance of the code becomes easier. No need to modify every JSP page , when you need a change in business logic .Just change the JSP tag

– Easy to use as it has HTML-like syntax.

Some of the built-in tags in JSP are jsp:useBean, jsp:getProperty, jsp:forward , etc .. and in struts framework bean:define, logic:iterate , etc.. This tutorial shows you how to build and implement JSP custom tags in easy steps.

What is JSP custom tag?  JSP custom tag is a user-defined tag that follows a special XML syntax that can be used in a JSP to do specified task without using scriptlet code. Each custom tag is associated with a Java class (tag handler class) to process the specified task. When a custom tag is processed, the corresponding tag handler class is invoked to process it, which is almost similar to the call to the JavaBean. When a java bean in a JSP is called, the corresponding java class file is executed. Custom tags are usually distributed in the form of a tag library which is a list of tag and tag handler class.

Syntax of Custom tags :

A simple tag contains no body and no attributes:

<prefix:tag />

OR

A simple tag contains attributes and no body :

<prefix:tag attr1=”value” .. attrN=”value” />

OR

A tag contains attributes and body :

<prefix:tag attr1=”value” .. attrN=”value” >
body
</prefix:tag>

where prefix distinguishes tags for a library, tag is the tag identifier, and attr1 … attrN are attributes that modify the behavior of the tag.

How to build custom tags ?. The following steps are used to build custom tags.

1. Decide and name the tag to build

2. Write the tag handler class for the tag ,tag handler is a Java class that performs the action of a custom tag.

3. Create the tag library descriptor (TLD) which contains mappings between our custom tag and the tag handler java class

4. Place the TLD file and Tag handler classes in a location so that the application can access.

5. Make a Reference of the TLD file to the JSP .

Let us discuss the above steps in detail

1. Decide and name the tag to build and implement. Also decide whether to build tag with body OR tag without body. You can pass information either as attributes or as body to the tag handler class to process it. If you want to pass simple string or simple expression which generates simple string, it is better to pass it as attribute. Let us build a tag without body and with 3 attributes.

<fmt:formatDate dateString=”value” inFormat=”value” outFormat= “value” /> – which accepts the date string as input in the format inFormat and displays the date in the outFormat

2. Write the tag handler class :

Now let us write the tag handler class for the above tag.  javax.servlet.jsp.tagext package contains the classes and interfaces to implement simple tag handlers. You can write tag handler class for the custom tag with body content between the start and end tag by implementing the interface BodyTag or IterationTag OR by extending BodyTagSupport class which implements BodyTag interface and adds additional methods including getter methods for the bodyContent property and methods to get at the previous out JspWriter.

       In our example , we are going to write tag handler class for the custom tag without body content and with 3 attributes (Simple tag) by implementing the interface Tag OR by extending TagSupport class which implements Tag and IterationTag interfaces and adds additional methods including getter methods for the properties in Tag. The following code is the tag handler class for the custom tag <fmt:formatDate dateString=”value” inFormat=”value” outFormat= “value” />

If the date string is in the format “dd/mm/yyyy” , then the inFormat should be “dd/MM/yyyy” , and if you want to display the date in the format dd/mmm/yyyy ie. 22 Feb 2012 , then the outFormat should be “dd/MMM/yyyy”. And special thing about this tag is, if you set outFormat=”locale”, it finds your current locale, and displays the date in the current locale format.


package customTags;
/**
 * @author VKJ
 */
 import javax.servlet.jsp.tagext.*;
 import javax.servlet.jsp.*;
 import javax.servlet.http.*;
 import java.io.IOException;
 import java.text.*;
 import java.util.*;

public class formatDate extends TagSupport{
 private String inFormat="";
 private String outFormat="";
 private String dateString="";
 public int doStartTag() throws javax.servlet.jsp.JspException{
 HttpServletRequest request;
 JspWriter out;
 Locale locale;
 DateFormat df;
 String date;
 Date dt=new Date();
 request = ( HttpServletRequest )pageContext.getRequest();
 locale = request.getLocale(); // to get the current locale
 DateFormat sdfIn, sdfOut;
 sdfIn =new SimpleDateFormat(inFormat);
 if (outFormat.equalsIgnoreCase("locale"))
 sdfOut = SimpleDateFormat.getDateInstance(SimpleDateFormat.FULL, locale);
 else
 sdfOut =new SimpleDateFormat(outFormat);
 try
 {
 dt=sdfIn.parse(dateString);
 }catch (Exception e){
 throw new JspException( e.getMessage() );
 }

 date = sdfOut.format(dt);

 try {
 out = pageContext.getOut();
 out.print( date );
 } catch( IOException e ) {
 throw new JspException( e.getMessage() );
 }

return Tag.SKIP_BODY;

}
 public void setDateString(String string) {
 dateString = string;
 }

 public void setInFormat(String string) {
 inFormat = string;
 }

public void setOutFormat(String string) {
 outFormat = string;
 }
 }

In the above code, tag handler class extends TagSupport class instead of implementing Tag interface because TagSupport class is a concrete class that fully implements the methods declared in the Tag interface. Here we implement only the doStartTag() method which is required for our custom tag. doStartTag() method is invoked when the start tag is encountered and returns SKIP_BODY, because our simple tag has no body. Now how to send the processed output to the output stream. pageContext object is used to get the output buffer for sending content .

3. Create the tag library descriptor (TLD) :

Next step is to create tag library descriptor (TLD) that maps the custom tag and the Java class. The TLD file is a XML document which contains the mappings between our custom tag and the tag handler class and the attributes and their validations required for the custom tag. TLDs are used by a JSP container to validate the tags. Extension for the file is .tld. For more example, please visit TLD file Sample.

TLD file for our example is as follows.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>formatDate</shortname>
<uri>customTags.formatDate</uri>
<tag>
<name>formatDate</name>
<tagclass>customTags.formatDate</tagclass>
<bodycontent>empty</bodycontent>

<attribute>
 <name>dateString</name>
 <required>true</required>
 <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
 <name>inFormat</name>
 <required>true</required>
 </attribute>
 <attribute>
 <name>outFormat</name>
 <required>true</required>
 </attribute>
</tag>
</taglib>

        In the above xml , <required>true</required> means this attribute is mandatory. <rtexprvalue>true</rtexprvalue> means this attribute accepts string and Runtime Expression .<elexprvalue>true </elexprvalue> means it can support EL (Expression Language).

4. Place the TLD file and Tag handler classes in a location such that the application can access.

Now the Tag handler class ( formatDate in our example) and TLD file (formatDate.tld in our example) is ready. I have developed the above Tag handler class under the package customTags. Once Tag handler class is completed, compile it and place the class file in the folder WEB-INF/classes. If you use any development environment, when you re-build the project, the class file will be automatically copied to the classes folder. Place the TLD file in the folder WEB-INF. If you need to develop several tags, then better to make a JAR file of all tag handler classes and place it in the lib folder.

5. Make a Reference of the TLD file to the JSP .

The following two ways are there to make reference between our JSP pages and the tag library

1. You can directly add a JSP declaration to any jsp page that needs to use the tag

<%@ taglib uri=”/WEB-INF/formatDate.tld” prefix=”fmt”%>

2. To make a static reference, add the following entry to the web.xml file


<taglib>
<taglib-uri>formatDate</taglib-uri>
<taglib-location>/WEB-INF/formatDate.tld</taglib-location>
</taglib> 

then you can add the following JSP declaration to any jsp page

<%@ taglib uri=”formatDate” prefix=”fmt”%>

How to use the above Custom tag (i.e. formatDate) in your application

Tag syntax : <fmt:formatDate dateString=”value” inFormat=”value” outFormat= “value” />

Attributes :

dateString : accepts valid date string or expression which returns valid date string. e.g “2012-02-15”. required = true , runtime expression = true .

inFormat : accepts any valid date format string. eg. “yyyy-MM-dd” . required = true , runtime expression = false

outFormat : accepts any valid date format string. eg. “dd/MMM/yyyy” . required = true , runtime expression = false

Example usage :

1. <fmt:formatDate dateString=”2012-02-15″ inFormat=”yyyy-MM-dd” outFormat=”dd/MMM/yyyy”/> which prints the date as “15/Feb/2012”

2. <fmt:formatDate dateString=”2012-02-15″ inFormat=”yyyy-MM-dd” outFormat=”locale”/>, which displays the output based on the current locale format retrieved from the request object . Output : Wednesday, February 15, 2012


3. <logic:notEmpty name="empForm" property="empDetails">
 <logic:iterate id="employee" name="empForm" property="empDetails" >
 EmpCode : <bean:write name="employee" property="empCode" />
 .....
 .....
 <logic:notEmpty name="employee" property="dob">
 <bean:define id="dobvar" name="employee" property="dob" type="java.lang.String"/>
 Date of Birth : <fmt:formatDate dateString="<%=dobvar%>" inFormat="yyyy-MM-dd" outFormat="locale"/>
 </logic:notEmpty>
 .....
 </logic:iterate>
 </logic:notEmpty>

The above struts code (partly) prints the employees with date of birth in the format current locale.

Leave a Reply