Monday, June 25, 2012

JSP Custom Tag: Simple Tag


Introduction

From official site:
A custom tag is a user-defined JSP language element. When a JSP page containing a custom tag is translated into a servlet, the tag is converted to operations on an object called a tag handler. The Web container then invokes those operations when the JSP page's servlet is executed.

Custom tags have a rich set of features. They can

Be customized via attributes passed from the calling page.
Access all the objects available to JSP pages.
Modify the response generated by the calling page.
Communicate with each other. You can create and initialize a JavaBeans component, create a variable that refers to that bean in one tag, and then use the bean in another tag.
Be nested within one another, allowing for complex interactions within a JSP page.

In short, it can encapsulate logic, style, script together and can make your page cleaner and do something more complex/powerful.

This post is about how to create a simple tag to display error message in specific style and do specific action.

Pre-define

The spec of the simple tag:
1. Output the given msg with default style "color: red; font-weight:bold;font-style:italic;", you can provide a css class to styleClass to override the default style.
2. Default alert msg+': '+msgDescription when clicked, you can provide a javascript function to onClick to override the default action.


The Program

ErrMsg.java

package test.tag.custom;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Error Message JSP Custom Tag, simple tag, no tag body
*
*/
public class ErrMsg extends TagSupport {
    private static final long serialVersionUID = -2121640315534820214L;

    private String _msg; //-- error message
    private String _msgDescription; //-- error description
    private String _styleClass; //-- css class
    private String _onClick; // script to execute when clicked
    /**
     * tag attribute setter
     * @param msg The error messsage
     */
    public void setMsg(String msg) {
        _msg = msg;
    }
    /**
     * tag attribute setter
     * @param msgDescription The error description
     */
    public void setMsgDescription(String msgDescription) {
        _msgDescription = msgDescription;
    }
    /**
     * tag attribute setter
     * @param msgStyle The css class
     */
    public void setStyleClass(String styleClass){
        _styleClass = styleClass;
    }
    /**
     * tag attribute setter
     * @param onClick The script to execute while clicked
     */
    public void setOnClick (String onClick) {
        _onClick = onClick;
    }
    /**
     * do start tag, this function will be called when parsing <errMsg msg=...>
     */
    public int doStartTag() throws JspException {
        try {
            if(_msg != null){
                //-- output span's start tag
                pageContext.getOut()
                    .print("<span");

                //-- output default style or specified class
                if (_styleClass == null) {
                    pageContext.getOut()
                        .print(" style=\"color: red; font-weight:bold;font-style:italic;\"");
                } else {
                    pageContext.getOut()
                        .print(" class=\""
                                + _styleClass
                                + "\"");
                }
                //-- output default script or specified function
                if (_onClick == null) {
                    pageContext.getOut()
                        .print(" onclick=\"alert('"
                                + _msg
                                + (_msgDescription == null? "" : ": "+_msgDescription)
                                + "');\"");
                } else {
                    pageContext.getOut()
                        .print(" onclick=\""
                                + _onClick+"\"");
                }
                // finish span's start tag, output _msg.
                pageContext.getOut()
                    .print(">" + _msg);
            }
        } catch (Exception e) {
            throw new JspException("Error: IOException while writing to client");
        }
        // simple tag, no body.
        return SKIP_BODY;
    }
    /**
     * do end tag, this function will be called when parsing &lt;/errMsg&gt;
     */
    public int doEndTag() throws JspException {
        try {
            // output span's end tag
            pageContext.getOut().print("</span>");
        } catch (IOException ioe) {
            throw new JspException("Error: IOException while writing to client");
        }
        //-- continue processing the page
        return EVAL_PAGE;
    }
}


The tag definition

Create a folder META-INF at project root and write a xxx.tld in it, the content of the tld file is as 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</tlibversion>
    <jspversion>1.1</jspversion>
    <!-- short name -->
    <shortname>ct</shortname>
    <!-- uri -->
    <uri>http://test.tag.custom/jsp/impl/taglib</uri>
    <!-- Message Tag -->
    <tag>
        <!-- tag name -->
        <name>errMsg</name>
        <!-- tag class path -->
        <tagclass>test.tag.custom.ErrMsg</tagclass>
        <!-- simple tag do not have body -->
        <bodycontent>empty</bodycontent>
        <!-- attributes -->
        <attribute>
            <!-- attribute name -->
            <name>msg</name>
            <!-- required or not -->
            <required>false</required>
            <!-- el enable or not (eval at runtime) -->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <!-- attribute name -->
            <name>msgDescription</name>
            <!-- required or not -->
            <required>false</required>
            <!-- el enable or not (true denotes can be eval at runtime) -->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>styleClass</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
        <attribute>
            <name>onClick</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>


Export jar

When the java file and tld file are ready, we have to export it as xxx.jar so we can use it in any web project:

1. Right click on java file -> Export



2. Select 'JAR file' -> Next



3. Check the folders 'src' and 'META-INF' are selected, choose export destination then click Finish.





Test it

After the jar is exported, we can copy it into WEB-INF/lib and write a jsp to test it.

errMsgTest.jsp

<%@ page isErrorPage="true" language="java"
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page isELIgnored ="false" %>
<!-- use the custom taglib with prefix ct -->
<%@taglib prefix="ct" uri="http://test.tag.custom/jsp/impl/taglib"%>
<html>
    <head>
        <meta http-equiv="Content-Type" 
            content="text/html; charset=UTF-8"/>
        <title>EL Math Practice</title>
        <style>
            .err_msg_class {
                color: #AE4386;
                font-size: 22px;
            }
        </style>
        <script type="text/javascript">
            function onErrClick (msg) {
                // hide the message after clicked
                msg.style.display = 'none';
            }
        </script>
    </head>
    <body>
        <!-- Use default style and action -->
        <ct:errMsg msg="Error" msgDescription="This is test error message" />
        <!-- Use custom style and action -->
        <ct:errMsg msg="Error" styleClass="err_msg_class" onClick="onErrClick(this);" />
    </body>
</html>


The result

Test page:



Click on default errMsg (the red one):



Click on customized errMsg:




Reference:
http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags.html

Download:

The full project is at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/CustomTagPractice

Wednesday, June 6, 2012

ZK Quick Start


This post is the Quick Start guide of ZK, talking about how to getting it started quickly, NO ZK Studio, NO Maven, just the simple clear traditional way.

1. Download Eclipse:
1.1: Go to Eclipse official site (http://www.eclipse.org/, for 2012-06-06)
1.2: Click Downloads

1.3: Click Eclipse IDE for Java EE Developers (I choose 32 Bit version)

1.4: Click download button to download it.


2. Download Tomcat:
2.1: Go to Tomcat official site (http://tomcat.apache.org/, for 2012-06-06)
2.2: Click 'Tomcat 7.0'

2.3: Find the 'Binary Distributions' and download it

3. Download ZK
3.1: Go to ZK official site (http://www.zkoss.org/, for 2012-06-06)
3.2: Click Downloads -> ZK

3.3: Click 'Download ZK CE' to download it


4. Start Eclipse:
4.1: Extract the downloaded file eclipse-jee-indigo-SR2-win32.zip

4.2: Create a workspace folder for Eclipse

4.3: Double-click on eclipse/eclipse.exe to open it, choose the workspace then click 'OK'

4.4: Click 'Workbench' to enter workbench

5. Add Tomcat Server in Eclipse
5.1: Extract the downloaded file apache-tomcat-7.0.27-windows-x86.zip

5.2: Right-click in Eclipse's Servers view -> New -> Server

5.3: Select Apache/Tomcat v7.0 Server, click next

5.4: Choose server folder, click finish

6. Create Test Project
6.1: Click File -> New -> Dynamic Web Project

6.2: Enter Project name then click Finish

6.3: Extract the downloaded file zk-bin-6.0.1.zip

6.4: Copy all jar files under zk-bin-6.0.1\dist\lib to WebContent/WEB-INF/lib
6.5: Copy zk-bin-6.0.1\dist\WEB-INF\web.xml to WebContent/WEB-INF/

6.6: Right-click on WebContent -> New -> File, create a file 'index.zul' under WebContent

6.7: Edit index.zul as below:

7. Run Test Project
7.1: Right-click on server, click Add and Remove

7.2: Select test project, click Add then click Finish

7.3: Click 'Run' button

7.4: Open browser then go to the test project

7.6: Click the test button, a label will appear


Finish