Custom tags and JSPs interaction

Custom tags are not new to any JSP programmer.  In this article,  I would like to create a custom tag that demonstrates how a custom tag interacts with JSP using attributes. 

In case you are new to custom tags in JSP 2.0, see article Creating and using custom tags.

I will create a custom tag called <query> , which takes an SQL query and makes data retrieved by the query available to JSP through attributes.The following are the steps to be taken to develop this tag and use it. 

The first step is to create the tag handler as follows:
package st;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;


public class QueryHandler extends SimpleTagSupport {
    private String sql;
    
    public void doTag() throws JspException {
        JspWriter out=getJspContext().getOut(); 
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","hr","hr");
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(sql);
            JspContext ctx = getJspContext();
            
            // get data related to ResultSet
            ResultSetMetaData rsmd = rs.getMetaData();
            int count = rsmd.getColumnCount();
            JspFragment f=getJspBody();
            
            while ( rs.next()) {
                for(int i = 1 ; i <= count ; i ++ ) {
                   // Create an attribute for each column. 
                   // Column name is attribute name and value is attribute's value.
                   ctx.setAttribute( rsmd.getColumnName(i), rs.getString(i));
                }                      
                // process the body of the tag and send result to JSPWriter
                f.invoke(out);
            }
            rs.close();
            con.close();
        } catch (Exception ex) {
            throw new JspException(ex.getMessage());
        }
    }
    // attribute sql 
    public void setSql(java.lang.String value) {
        this.sql = value;
    }
}


In the above Tag Handler, we use SQL query passed through attribute sql to retrieve data. The data is placed in ResultSet. For each row of the ResultSet we create a set of attributes - one for each column. The name of the attribute is column name and value is column's value.  To get names of columns we have to get ResultSetMetaData object from ResultSet.

NOTE : The column names are in uppercase. So even the attribute names are in uppercase. In case you want to create attributes with lowercase names, use  toLowerCase() method of String class as follows:
ctx.setAttribute( rsmd.getColumnName(i).toLowerCase() , rs.getString(i));

The following is tab library descriptor (st.tld) for the above tag.
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" 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 web-jsptaglibrary_2_0.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>Srikanth Technologies Tags</short-name>
  <uri>/WEB-INF/tlds/st</uri>
  <tag>
    <name>query</name>
    <tag-class>st.QueryHandler</tag-class>
    <body-content>scriptless</body-content>
    <attribute>
      <name>sql</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.String</type>
    </attribute>
  </tag>
</taglib>


Now, let us register st.tld in a JSP using taglib directive and use <query> tag. The following JSP shows how to use it.
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib uri="/WEB-INF/tlds/st.tld" prefix="st"%> 


<!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=UTF-8">
        <title>Using Query Tag</title>
    </head>
    <body>
    <h1>Query</h1>
    
    <ul>
        <st:query  sql="select * from departments where department_id <= 50">
             <li> ${DEPARTMENT_ID}, ${DEPARTMENT_NAME}   
        </st:query>
    </ul>
    
    
    <table border="1">
        <tr><th>Title</th><th>Min Salary </th></tr>
        <st:query  sql="select * from jobs">
            <tr><td> ${JOB_TITLE} </td> <td> ${MIN_SALARY} </tr>
        </st:query>
    </table>
        
    </body>
</html>


First usage of query tag is to retreive details from DEPARTMENTS table. Attributes DEPARTMENT_ID and DEPARTMENT_NAME are created from tag handler. Those attributes are used in JSP using Expression Langauge (EL) syntax. By making data available using attributes, we allow JSP to display data in the way it wants. It is demonstrated by second usage of <query> tag as we used a table to display the data of attributes.

This article shows how to make use of the following:

The concept of custom tags is very powerful. JSTL, JSF and even frameworks such as Struts make use of custom tags extensively. So, it is worth understanding how custom tags and JSPs interact.

Keep Learning
Srikanth.