Posts Tagged ‘Custom Tags’

Free SCWCD Mock Exam for Custom Tags

9 May 2009

This practice exam focuses on Custom Tags. For those using Head First Servlets and JSP, 2nd Edition it is a perfect companion for chapter 10.

Custom Tags is the most powerful feature of the JSP technology. This free material should be useful for those preparing for the Sun Certified Web Component Developer certification.

To get basic skills before going on, you may consider this compact tutorial first.

Click here to read more…

Custom Tags Tutorial

24 January 2009

This tutorial presents practical skills for Custom Tags; the most powerful feature of the JSP technology. Its purpose is to be a good review for those preparing for Sun Certified Web Component Developer certification and, at the same time, a good reference at work.

  1. Skills for Tag Files
  2. Skills for Simple Tag handlers
  3. Skills for Classic Tag handlers
  4. Body manipulation of Classic Tags

Thank you.

Custom Tags 4 – Body manipulation of Classic Tags

19 January 2009

This post explains how to manipulate the body of a classic tag.

Step 1. Write a BodyTagSupport and provide its doAfterBody() method.

package my;
public class Body extends BodyTagSupport {
  public int doAfterBody() {
    try {
      final String body = bodyContent.getString();
      final StringBuilder result = new StringBuilder();
      for (int index = 0; index < body.length(); index = index + 2) {
        result.append(body.charAt(index));
      }
      bodyContent.getEnclosingWriter().print(result.toString());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return SKIP_BODY;
  }
}

Step 2. Declare it in a TLD.

<taglib ...>
  <uri>nikojava</uri>
  <tag>
    <name>body</name>
    <tag-class>my.Body</tag-class>
    <body-content>scriptless</body-content>
  </tag>
</taglib>

Step 3. Call it!

<%@ taglib prefix="mari" uri="nikojava" %>
<html>
  <body>
    (Before)
    <mari:body>ABABABABABABAB</mari:body>
    (After)
  </body>
</html>
Filtering the even characters of a classic tag's body

Filtering the even characters of a classic tag's body

As a result, only the characters at an even position (0, 2, 4, etc.) are printed!

Explanation

BodyTagSupport IS-A TagSupport. However it offers an extra weapon: EVAL_BODY_BUFFERED. If doStartTag() returns this value, then a series of methods is invoked: setBodyContent(BodyContent), then doInitBody(), then the body is evaluated and doAfterBody() is about to execute. At this point we do have access to the actual body content.

In the above example doStartTag() is not overriden, so by default EVAL_BODY_BUFFERED is returned. The actual content is taken as a string,

  final String body = bodyContent.getString();

and its even characters are selected:

  for (int index = 0; index < body.length(); index = index + 2) {
    result.append(body.charAt(index));
  }

More examples

Color alternate letters

public int doAfterBody() {
  try {
    final String body = bodyContent.getString();
    final StringBuilder result = new StringBuilder();
    for (int index = 0; index < body.length(); index++) {
      if (isOdd(index)) {
        result.append("<span style='color:red'>");
        result.append(body.charAt(index));
        result.append("</span>");
      } else {
        result.append(body.charAt(index));
      }
    }
    bodyContent.getEnclosingWriter().print(result.toString());
  } catch (Exception e) {
    e.printStackTrace();
  }
  return SKIP_BODY;
}
private boolean isOdd(int number) {
  return number % 2 == 1;
}
<%@ taglib prefix="mari" uri="nikojava" %>
<html>
  <body>
    (Before)
    <mari:body>ABABABABABABAB</mari:body>
    (After)
  </body>
</html>
Coloring the even characters of a classic tag's body

Coloring the even characters of a classic tag's body

Remove capital letters

public int doAfterBody() {
  try {
    final String body = bodyContent.getString();
    final StringBuilder result = new StringBuilder();
    for (int index = 0; index < body.length(); index++) {
      final char current = body.charAt(index);
      if (!Character.isUpperCase(current)) {
        result.append(current);
      }
    }
    bodyContent.getEnclosingWriter().print(result.toString());
  } catch (Exception e) {
    e.printStackTrace();
  }
  return SKIP_BODY;
}
<%@ taglib prefix="mari" uri="nikojava" %>
<html>
  <body>
    (Before)
    <mari:body>Google Sun JBoss</mari:body>
    (After)
  </body>
</html>
Disposing the capital letters of a custom tag's body

Disposing the capital letters of a custom tag's body

Have fun

public int doAfterBody() {
  try {
    final StringBuilder body = new StringBuilder(bodyContent.getString());
    final int initialSize = body.length();
    for (int index = 0; index < initialSize; index++) {
      bodyContent.getEnclosingWriter().append(body);
      bodyContent.getEnclosingWriter().append("<br />");
      body.deleteCharAt(body.length() - 1);
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
  return SKIP_BODY;
}
<%@ taglib prefix="mari" uri="nikojava" %>
<html>
  <body>
    <mari:body>Microsystems</mari:body>
  </body>
</html>
Having fun with the body of a classic tag

Having fun with the body of a classic tag

Custom Tags 3 – Skills for Classic Tag handlers

15 January 2009

This post presents the basic skills of classic tag handling for the JSP technology.

Here’s an overview of the hierarchy. The arrows denote an IS-A relationship.

Hierarchy of Classic tag handlers

Hierarchy of Classic Tag handlers

Step 1. Write a TagSupport and provide its doStartTag() method.

package my;
public class Classic extends TagSupport {
  public int doStartTag() throws JspException {
    try {
      pageContext.getOut().print("Hello from a classic tag handler!!");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return SKIP_BODY;
  }
}

Step 2. Declare it in a TLD.

<taglib ...>
  <uri>nikojava</uri>
  <tag>
    <name>classic</name>
    <tag-class>my.Classic</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>

Step 3. Call it!

<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic />
  </body>
</html>
Invoking a classic tag

Invoking a classic tag

Process its body

Just return EVAL_BODY_INCLUDE to make the body evaluated,

public class Classic extends TagSupport {
  public int doStartTag() throws JspException {
    try {
      pageContext.getOut().print("This is my body: ");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return EVAL_BODY_INCLUDE;
  }
}

as long as the tag is declared to have a body.

<tag>
  <name>classic</name>
  <tag-class>my.Classic</tag-class>
  <body-content>scriptless</body-content>
</tag>
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic>Really useful contents!</show:classic>
  </body>
</html>
Accessing the body of a classic tag

Accessing the body of a classic tag

Define a body attribute

It’s easy to define attributes right inside the body of the tag.

public class Classic extends TagSupport {
  public int doStartTag() throws JspException {
    pageContext.setAttribute("friend", "Nikos");
    return EVAL_BODY_INCLUDE;
  }
}
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic>Hello my friend ${friend}!!</show:classic>
  </body>
</html>
Using an attribute inside the body of a classic tag

Using an attribute inside the body of a classic tag

Define a tag attribute

An attribute is defined as a setter method,

public class Classic extends TagSupport {
  private String friend;
  public int doStartTag() throws JspException {
    try {
      pageContext.getOut().append("Hey you " + friend + "!!");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return EVAL_BODY_INCLUDE;
  }
  public void setFriend(String friend) {
    this.friend = friend;
  }
}

that is also declared in the TLD.

<tag>
  <name>classic</name>
  <tag-class>my.Classic</tag-class>
  <body-content>empty</body-content>
  <attribute>
    <name>friend</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic friend="Niko" />
  </body>
</html>
Using a tag attribute

Using a tag attribute

Dynamic attributes

To process such attributes you should implement the DynamicAttributes and its single method.

public class Classic extends TagSupport implements DynamicAttributes {
private Map<String, Object> map = new HashMap<String, Object>();
  public void setDynamicAttribute(String uri, String name, Object value) {
    map.put(name, value);
  }
public int doStartTag() throws JspException {
  try {
    JspWriter out = pageContext.getOut();
    out.append("These are the dynamic attributes:");
    out.append("<ul>");
    for (Map.Entry<String, Object> element : map.entrySet()) {
      out.append("<li>");
      out.append(element.getKey() + " ⇒ " + element.getValue());
      out.append("</li>");
    }
    out.append("</ul>>");
  } catch (IOException e) {
    e.printStackTrace();
  }
  return SKIP_BODY;
}
}

The doStartTag() method simply displays the name and value of each dynamic attribute.

<tag>
  <name>classic</name>
  <tag-class>my.Classic</tag-class>
  <body-content>empty</body-content>
  <dynamic-attributes>true</dynamic-attributes>
</tag>
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic custom="tag" open="source" javafx="cool" />
  </body>
</html>
Dynamic attributes in a classic tag

Dynamic attributes in a classic tag

Reevaluate the body

When the doStartTag() method returns EVAL_BODY_INCLUDE, we can evaluate the body again and again. This is possible using the doAfterBody() method.

public class Classic extends TagSupport {
  private int counter;
  public int doStartTag() throws JspException {
    counter = 0;
    return EVAL_BODY_INCLUDE;
  }
  public int doAfterBody() throws JspException {
    while (counter < 3) {
      counter++;
      return EVAL_BODY_AGAIN;
    }
    return SKIP_BODY;
  }
}
<tag>
  <name>classic</name>
  <tag-class>my.Classic</tag-class>
  <body-content>scriptless</body-content>
</tag>
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    <show:classic>Hello </show:classic>
  </body>
</html>
Iterating over the body of a classic tag again and again

Iterating over the body of a classic tag again and again

Skip the rest of the page

This is accomplished by overriding the doEndTag() method.

public class Classic extends TagSupport {
  public int doStartTag() throws JspException {
    return EVAL_BODY_INCLUDE;
  }
  public int doEndTag() throws JspException {
    return SKIP_PAGE;
  }
}
<tag>
  <name>classic</name>
  <tag-class>my.Classic</tag-class>
  <body-content>scriptless</body-content>
</tag>
<%@ taglib prefix="show" uri="nikojava" %>
<html>
  <body>
    (Start of page)
    <show:classic>Hello from a classic tag!</show:classic>
    (End of page)
  </body>
</html>
Skipping the rest of the page from a classic tag

Skipping the rest of the page from a classic tag

Indeed, the last part of the page is never sent to the client.

Review

doStartTag method is called first. It may return:

  1. EVAL_BODY_INCLUDE = evaluate the body once.
  2. SKIP_BODY = go on, do not evaluate the body of the tag.

doAfterBody method is called only if doStartTag() returns option 1. It may return:

  1. EVAL_BODY_AGAIN = evaluate the body again.
  2. SKIP_BODY = just go on, stop evaluating the body.

doEndTag method is called last. It may return:

  1. SKIP_PAGE = skip the rest of the page.
  2. EVAL_PAGE = proceed normally to the rest of the page.

Custom Tags 2 – Skills for Simple Tag handlers

14 January 2009

This post presents the basic skills of simple tag handling for the JSP technology. In detail, we’ll see how to:

Here’s an overview of the hierarchy. The arrows denote an IS-A relationship.

Hierarchy of Simple tag handlers

Hierarchy of Simple tag handlers

Step 1. Write a SimpleTagSupport and provide its doTag() method.

package my;
public class Simple extends SimpleTagSupport {
  public void doTag() throws IOException, JspException {
    getJspContext().getOut().append("Hello from a simple tag handler!!");
  }
}

Step 2. Declare it in a TLD.

<taglib ...>
  <uri>nikojava</uri>
  <tag>
    <name>simple</name>
    <tag-class>my.Simple</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>

Step 3. Call it!

<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    <yo:simple />
  </body>
</html>
Invoking a simple tag handler

Invoking a simple tag handler

Process its body

This is possible using the invoke method of JspFragment,

public class Simple extends SimpleTagSupport {
  public void doTag() throws IOException, JspException {
    getJspContext().getOut().print("This is my body:<br />");
    getJspBody().invoke(null);
  }
}

as long as the tag is allowed to have a body.

<tag>
  <name>simple</name>
  <tag-class>my.Simple</tag-class>
  <body-content>scriptless</body-content>
</tag>
<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    <yo:simple>Some useful content</yo:simple>
  </body>
</html>
Accessing the body of a simple custom tag

Accessing the body of a simple custom tag

Define an attribute inside its body

Also, you may define attributes right inside the body of the tag.

public class Simple extends SimpleTagSupport {
  public void doTag() throws IOException, JspException {
    getJspContext().setAttribute("friend", "Niko");
    getJspBody().invoke(null);
  }
}
<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    <yo:simple>Hello ${friend}!!</yo:simple>
  </body>
</html>
Using an attribute inside the tag's body

Using an attribute inside the tag's body

Define a tag attribute

An attribute is defined as a setter method,

public class Simple extends SimpleTagSupport {
  private String friend;
  public void doTag() throws IOException, JspException {
    getJspContext().getOut().append("Hello " + friend + "!!");
  }
  public void setFriend(String friend) {
    this.friend = friend;
  }
}

that is also declared in the TLD.

<tag>
  <name>simple</name>
  <tag-class>my.Simple</tag-class>
  <body-content>empty</body-content>
  <attribute>
    <name>friend</name>
    <required>true</required>
    <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>
<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    <yo:simple friend="Niko" />
  </body>
</html>
Using an attribute inside the tag's body

Using an attribute inside the tag's body

Dynamic attributes

To process such attributes you should implement the DynamicAttributes; an interface with a single method.

public class Simple extends SimpleTagSupport implements DynamicAttributes {
  private Map<String, Object> map = new HashMap<String, Object>();
  public void setDynamicAttribute(String uri, String name, Object value) {
    map.put(name, value);
  }
  public void doTag() throws IOException, JspException {
    JspWriter out = getJspContext().getOut();
    out.append("These are the dynamic attributes:");
    out.append("<ul>");
    for (Map.Entry<String, Object> element : map.entrySet()) {
      out.append("<li>");
      out.append(element.getKey() + " &rArr; " + element.getValue());
      out.append("</li>");
    }
    out.append("</ul>");
  }
}

The doTag() method simply displays the name and value of each dynamic attribute.

<tag>
  <name>simple</name>
  <tag-class>my.Simple</tag-class>
  <body-content>empty</body-content>
  <dynamic-attributes>true</dynamic-attributes>
</tag>
<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    <yo:simple friend="Niko" casoline="soft" more="lagi" />
  </body>
</html>
Displaying the dynamic attributes

Displaying the dynamic attributes

Skip the rest of the page

This is accomplished by throwing a SkipPageException at the desired place.

public class Simple extends SimpleTagSupport {
  public void doTag() throws IOException, JspException {
    getJspContext().getOut().append("Encapsulation");
    throw new SkipPageException();
  }
}
<%@ taglib prefix="yo" uri="nikojava" %>
<html>
  <body>
    (Start of page)
    <yo:simple />
    (End of page)
  </body>
</html>
Skipping the rest of the page

Skipping the rest of the page