Monday, July 11, 2011

Struts Custom tag to support JSTL functions

The Struts Taglib component provides a set of JSP custom tag libraries that help developers create interactive form-based applications. There are tags to help with everything from displaying error messages to dealing with nested ActionForm beans.

Struts Taglib is composed of four distinct tag libraries: Bean, HTML, Logic, and Nested.
Bean  :   The bean tags are useful in defining new beans (in any scope) from a variety of possible sources, as well as a tag to render a particular bean (or bean property) to the output response.
HTML :    The HTML tags are used to create input forms, as well as other tags generally useful in the creation of HTML-based user interfaces. The output is HTML 4.01 compliant or XHTML 1.0 when in XHTML mode.
Logic   :  The Logic tags that are useful in managing conditional generation of output text, looping over object collections for repetitive generation of output text, and application flow management
Nested  :   The Nested tags extend the base Struts tags to allow them to relate to each other in a nested nature. The fundamental logic of the original tags doesn't change, except in that all references to beans and bean properties will be managed in a nested context.

A 'custom' tag is something which a browser will not understand, because it is not a pre-defined HTML tag. you need to write/tell the browser so that it understands what it is supposed to do.
A custom tag, is thus, a tag, you write in your Java Server Page. When the jsp compiler encounters that tag, it knows what to do with it. It generates the proper HTML after doing whatever it is supposed to do.

Custom Tag

   1. Write the tag handler class.
   2. Create the tag library descriptor (TLD).
   3. Make the TLD file and handler classes accessible.
   4. Reference the tag library.
   5. Use the tag in a JSP page.      

        * Tag Handlers implement one of three interfaces:

1.  Tag
    Implement the javax.servlet.jsp.tagext.Tag interface if you are creating a custom tag that does not need access to its interface. The API also provides a convenience class TagSupport that implements the Tag interface and provides default empty methods for the methods defined in the interface.

2.  BodyTag
    Implement the javax.servlet.jsp.tagext.BodyTag interface if your custom tag needs to use a body. The API also provides a convenience class BodyTagSupport that implements the BodyTag interface and provides default empty methods for the methods defined in the interface. Because BodyTag extends Tag it is a super set of the interface methods.

3.  IterationTag
    Implement the javax.servlet.jsp.tagext.IterationTag interface to extend Tag by defining an additional method doAfterBody() that controls the reevaluation of the body.
Sample Java program implements Custom Tag.

import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.Tag;

public class DateTag implements BodyTag {
    private PageContext pc = null;
    private Tag parent = null;
    private BodyContent bd = null;
    private boolean showInUpperCase;

    public boolean isShowInUpperCase() {
        return showInUpperCase;

    public void setShowInUpperCase(boolean showInUpperCase) {
        this.showInUpperCase = showInUpperCase;

    public void doInitBody() throws JspException {


    public void setBodyContent(BodyContent arg0) {
        bd = arg0;


    public int doAfterBody() {
        try {
            String bodyString = bd.getString();
            JspWriter out = bd.getEnclosingWriter();
            SimpleDateFormat simDate = new SimpleDateFormat("dd-MM-yyyy");
            out.print((bodyString + simDate.format(new Date())).toUpperCase());
            bd.clear(); // empty buffer for next evaluation
        } catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
        } // end of catch

        return SKIP_BODY;

    public int doEndTag() throws JspException {
        return EVAL_PAGE;

    public int doStartTag() throws JspException {
        return EVAL_BODY_AGAIN;

    public Tag getParent() {
        return parent;

    public void release() {
        pc = null;
        parent = null;


    public void setPageContext(PageContext arg0) {
        pc = arg0;

    public void setParent(Tag arg0) {
        parent = arg0;

     * Write a tag library descriptor.

      that will contain the mappings between our custom tag and the Java class (or classes) that will handle it. This library is defined within an XML document called a tag library descriptor (TLD). We'll call the TLD for our DateTag example DateTagLib.tld. Note that ".tld" is the standard extension for such files.
            <?xml version="1.0" encoding="ISO-8859-1" ?>
                <info>A simple tag library</info>

               <info>Display Date</info>
      Although not mandatory, the TLD file is usually placed under WEB-INF/tlds/.

     * Reference the Library    

    * Declare the TLD in the web.xml file. web.xml is the standard descriptor file for any web application. The TLD is declared like:
Using a Custom Tag in your page

Now that the custom tag is built and deployed, it can be used in a JSP by:
    * Declaring the TLD as a directive:
      <@ taglib uri="DateTag" prefix="test" %>
    * Using a tag "displayDate", which is a part of the TLD, in the JSP page:

      <test:displayDate attr1="value1" attr2="value2" />
As soon as the runtime encounters the "test" tag, it knows a tag in that library is going to be used. In the above example, "displayDate" in the library is used. When the runtime parses "<test:displayDate", the method of "displayDate" is triggered.

JSTL Functions 
JSTL functions are supported from version 1.1.

If you are in version 1.0 here is the steps to upgrade.

1. Reference the correct servlet specification in your deployment descriptor:

      <?xml version="1.0"?>
      <web-app version="2.4"
   2. Reference the correct JSTL uri in your JSP:

      <%@ taglib uri='' prefix='c'%>
      <%@ taglib uri='' prefix='c'%>

And ofcourse upgrade the JSTL jar in your class path.

The JSTL 1.1. library provides inbuilt function support .. refer

<%@ taglib uri=""
     prefix="c" %>
<%@ taglib uri=""
    prefix="fn" %>
<c:if test="${fn:length(param.username) > 0}" >
  <%@include file="response.jsp" %>

Use a Custom Tag with function support from Apache commons-lang.
Defining a Tag function in a web app

The TLD File

<!-- WEB-INF/tld/commons-lang.tld -->
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns=""
    <description>Tags used escape characters</description>
    <display-name>escape tags</display-name>
        <description>Escapes the characters in a String using HTML entities.</description>
        <function-signature>java.lang.String escapeHtml(java.lang.String)</function-signature>
        <description>Escapes the characters in a String using JavaScript String rules.</description>
        <function-signature>java.lang.String escapeJavaScript(java.lang.String)</function-signature>
        <description>Escapes the characters in a String using XML entities.</description>
        <function-signature>java.lang.String escapeXml(java.lang.String)</function-signature>


Somewhere near the top of the file.

<%@ taglib prefix="lang" uri="/WEB-INF/tld/commons-lang.tld"%>


// example of escaping for javascript

img.description = '${escape:javaScript(xxxxx)}';

// example of escaping an html attribute

title="${escape:html(pic.description)} ${escape:html(xxxxxx)}"
... />

No comments:

Post a Comment