In Previous articles, i have explained:
Life Cycle of JSP “Tag” interface.
Life Cycle of JSP “BodyTag” interface.
How to Create JSP Custom Tag – using Tag interface or TagSupport
we have seen that how to create the custom JSP tag using interface “Tag”, means tags which does not have a body. In this article, I will explain creating custom Tags which have a body. We can manipulate the content of body as we want.
So, create a class which implements interface “BodyTag“, in this article also I am not going to use Support classes. As it will not clear the basic idea.
package com.G2.CustomTag; import java.io.IOException; 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 DisplayDateBody 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; } @Override public void doInitBody() throws JspException { } @Override public void setBodyContent(BodyContent arg0) { bd = arg0; } @Override public int doAfterBody() { try { String bodyString = bd.getString(); JspWriter out = bd.getEnclosingWriter(); SimpleDateFormat frm = new SimpleDateFormat("dd-MMM-yyy EEEE"); if(showInUpperCase) { out.print((bodyString + frm.format(new Date())).toUpperCase()); }else{ out.print((bodyString + frm.format(new Date())).toLowerCase()); } bd.clear(); // empty buffer for next evaluation } catch (IOException e) { System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage()); e.printStackTrace(); } // end of catch return SKIP_BODY; } @Override public int doEndTag() throws JspException { return EVAL_PAGE; } @Override public int doStartTag() throws JspException { return EVAL_BODY_AGAIN; } @Override public Tag getParent() { return parent; } @Override public void release() { pc = null; parent = null; } @Override public void setPageContext(PageContext arg0) { pc = arg0; } @Override public void setParent(Tag arg0) { parent = arg0; } }
As per discussed in life cycle of BodtTag interface, two extra method is added to evaluate the body content of the tag.
Now create tld file in “WEB-INF/tlds” folder as shown below:
<?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.0</tlibversion> <jspversion>1.1</jspversion> <shortname>CustomTag</shortname> <uri>https://jitendrazaa.com/blog</uri> <info>Custom tags</info> <tag> <name>ShowDateWithCase</name> <tagclass>com.G2.CustomTag.DisplayDateBody</tagclass> <info>Custom tag used to display the current date with option to choose uppercase</info> <attribute> <name>showInUpperCase</name> <required>true</required> </attribute> </tag> </taglib>
Note here that attribute empty used in previous article is not used here, as we have bodycontent here, so it cannot be left blank.
Now create JSP page:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@taglib uri="/WEB-INF/tlds/CustomTags.tld" prefix="ct"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Custom Tag</title> </head> <body> <h2>Custom tag to display date</h2> <ct:ShowDateWithCase showInUpperCase="true"> Current Date is </ct:ShowDateWithCase> </body> </html>
We can also add the loop functionality in our code, what we have to do additionally is:
- Add one more attribute in tag library descriptor (tld) file.
- Create getter and setter for that attribute in Tag handler class.
- Add one more variable counter in tag handler class.
- initialize that variable in method doStartTag(), doInitBody() or any other setter of attribute.
- in method doAfterBody(), check the condition if counter<loopcounter then return “EVAL_BODY_BUFFERED” else return “SKIP_BODY”. EVAL_BODY_BUFFERED will tell the page compiler that eval that body again until the “SKIP_BODY” returned by the method.
Please leave your comment for any suggestion or queries.
Leave a Reply