JSP Custom Tags Example Tutorial

Filed Under: Java EE

Today we will look into JSP custom tags. Earlier we learned about JSP Action Elements, JSP EL and JSTL to avoid scripting elements in JSP pages. But sometimes even these are not enough and we might get tempted to write java code to perform some operations in JSP page. Fortunately JSP is extendable and we can create our own custom tags to perform certain operations.

Custom Tags in JSP

Let’s say we want to show a number with formatting with commas and spaces. This can be very useful for user when the number is really long. So we want some custom tags like below:

<mytags:formatNumber number="100050.574" format="#,###.00"/>

Based on the number and format passed, it should write the formatted number in JSP page, for above example it should print 100,050.57

We know that JSTL doesn’t provide any inbuilt tags to achieve this, so we will create our own custom tag implementation and use it in the JSP page. Below will be the final structure of our example project.

JSP Custom Tags, Custom tags in jsp

JSP Custom Tag Handler

This is the first step in creating custom tags in JSP. All we need to do is extend javax.servlet.jsp.tagext.SimpleTagSupport class and override doTag() method.

The important point to note is that we should have setter methods for the attributes we need for the tag. So we will define two setter methods – setFormat(String format) and setNumber(String number).

SimpleTagSupport provide methods through which we can get JspWriter object and write data to the response. We will use DecimalFormat class to generate the formatted string and then write it to response. The final implementation is given below.

NumberFormatterTag.java


package com.journaldev.jsp.customtags;

import java.io.IOException;
import java.text.DecimalFormat;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class NumberFormatterTag extends SimpleTagSupport {

	private String format;
	private String number;

	public NumberFormatterTag() {
	}

	public void setFormat(String format) {
		this.format = format;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	@Override
	public void doTag() throws JspException, IOException {
		System.out.println("Number is:" + number);
		System.out.println("Format is:" + format);
		try {
			double amount = Double.parseDouble(number);
			DecimalFormat formatter = new DecimalFormat(format);
			String formattedNumber = formatter.format(amount);
			getJspContext().getOut().write(formattedNumber);
		} catch (Exception e) {
			e.printStackTrace();
			// stop page from loading further by throwing SkipPageException
			throw new SkipPageException("Exception in formatting " + number
					+ " with format " + format);
		}
	}

}

Notice that I am catching exception thrown by format() method and then throwing SkipPageException to prevent further loading of the JSP page.

Creating JSP Custom Tag Library Descriptor (TLD) File

Once the tag handler class is ready, we need to define a TLD file inside the WEB-INF directory so that container will load it when application is deployed.

numberformatter.tld


<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
<description>Number Formatter Custom Tag</description>
<tlib-version>2.1</tlib-version>
<short-name>mytags</short-name>
<uri>https://journaldev.com/jsp/tlds/mytags</uri>
<tag>
	<name>formatNumber</name>
	<tag-class>com.journaldev.jsp.customtags.NumberFormatterTag</tag-class>
	<body-content>empty</body-content>
	<attribute>
	<name>format</name>
	<required>true</required>
	</attribute>
	<attribute>
	<name>number</name>
	<required>true</required>
	</attribute>
</tag>
</taglib>

Notice the URI element, we will have to define it in our deployment descriptor file. Also notice the attributes format and number that are required. body-content is empty means that the tag will not have any body.

JSP Custom Tag Deployment Descriptor Configuration

We will include the jsp custom tag library in web application using jsp-config and taglib elements like below.

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>JSPCustomTags</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <jsp-config>
  <taglib>
  	<taglib-uri>https://journaldev.com/jsp/tlds/mytags</taglib-uri>
  	<taglib-location>/WEB-INF/numberformatter.tld</taglib-location>
  </taglib>
  </jsp-config>
</web-app>

taglib-uri value should be same as defined in the TLD file. All the configuration is done now and we can use it in the JSP page.

Page using JSP Custom Tag

Here is a sample JSP page where I am using our number formatter jsp custom tag.

index.jsp


<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!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=US-ASCII">
<title>Custom Tag Example</title>
<%@ taglib uri="https://journaldev.com/jsp/tlds/mytags" prefix="mytags"%>
</head>
<body>

<h2>Number Formatting Example</h2>

<mytags:formatNumber number="100050.574" format="#,###.00"/><br><br>

<mytags:formatNumber number="1234.567" format="$# ###.00"/><br><br>

<p><strong>Thanks You!!</strong></p>
</body>
</html>

Now when we run our web application, we get JSP page like below image.

JSP Custom Tag Example, jsp custom tags

The JSP response page is showing the formatted number, similarly we can create more jsp custom tag handler classes. We can have multiple tags defined in the tag library.

If you have a lot of custom tag handler classes or you want it to provide as a JAR file for others to use, you need to include TLD files in the META-INF directory of the JAR file and include it in the web application lib directory. In that case, we don’t need to configure them in web.xml also because JSP container takes care of that.

That’s why when we use JSP Standard Tags, we don’t need to configure them in web.xml and we can declare them in JSP and use them. If you are not convinced, unzip the JSTL Tomcat standard.jar and you will find a lot of TLD files in the META-INF directory. 🙂

That’s all for custom tags in JSP, I hope you liked it.

Comments

  1. Ganesh Kandu says:

    Hi, How I Can Pass the X value from user input to my custom tag library

    Number Formatting Example

    Thanks You!!

    1. magicsign says:

      Use an attribute in the jsp tag within the jsp page, so in the JSP page it will look like ;

      In your tag library descriptor:

      yourCustomTag
      CustomTagJavaClass
      JSP
      Whatever description

      attribute1
      true

      In your java class you can retrieve it :

      private String attribute1;
      ….
      public int doStartTag() throws JspException {

      this.queryName = (String) ExpressionUtil.evalNotNull(
      “NewOrExistingMWRTag”, “queryName”, this.queryName, Object.class, this, pageContext);

      }

  2. kholofelo Maloma (@KholofeloMaloma) says:

    Good one!

    thanks. It is nice and simple.

  3. Nagarjuna says:

    Hi Sir

    Very nice tutorial. is it possible to add sales force tutorial in your website

  4. Anil Nivargi says:

    Very nice article but missed second approach…There are two ways to create the custom tags in JSP as follows,
    1)Tag handlers
    2)Tag files
    The tag handlers already explained above tutorials but second i.e tag files is not explained. Second is good way to create the custom tags. Please go through this
    adnjavainterview.blogspot.com

  5. Sufyan says:

    Nice example.but i see that no need to use web.xml to map TLd file and uri.
    Try it and will work.
    And regrading the URI:it must not be that complex one . it can be one word, i named it ‘randomThingsUri’
    and it works as a charm.

    Best Regards

  6. phimos says:

    i follow the step. why i cannot Run – error. ?
    HTTP Status 500 – The absolute uri: journaldev .com/jsp/tlds/mytags cannot be resolved in either web.xml or the jar files deployed with this application

    ——————————————————————————–

    type Exception report

    message The absolute uri: http:// journaldev.com/jsp/tlds/mytags cannot be resolved in either web.xml or the jar files deployed with this application

    description The server encountered an internal error that prevented it from fulfilling this request.

    exception

    org.apache.jasper.JasperException: The absolute uri: journaldev .com/jsp/tlds/mytags cannot be resolved in either web.xml or the jar files deployed with this application
    org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:56)
    org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:410)
    org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:117)
    org.apache.jasper.compiler.TagLibraryInfoImpl.generateTLDLocation(TagLibraryInfoImpl.java:311)
    org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:152)
    org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:410)
    org.apache.jasper.compiler.Parser.parseDirective(Parser.java:475)
    org.apache.jasper.compiler.Parser.parseElements(Parser.java:1427)
    org.apache.jasper.compiler.Parser.parse(Parser.java:138)
    org.apache.jasper.compiler.ParserController.doParse(ParserController.java:242)
    org.apache.jasper.compiler.ParserController.parse(ParserController.java:102)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:198)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:353)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:340)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:357)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

    note The full stack trace of the root cause is available in the Apache Tomcat/7.0.34 logs.

    ——————————————————————————–

    Apache Tomcat/7.0.34

  7. chandu says:

    awesome ……………….

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages