Developing Custom Tags for JSP

advertisement
JSP Custom Tags
Prerequisites
Servlet API

Mapping to JSP implicit objects
JavaServer Pages


Basic syntax
Implementation via servlet API
XML
What is a Custom Tag?
User defined JSP language elements
(as opposed to standard tags)
Encapsulates recurring tasks
Distributed in a “custom made” tag
library, which defines a set of related
custom tags and contains the objects
that implement the tags.
Why Use Custom Tags?
Improved separation of presentation and
implementation



Reduce/eliminate scripting tags
Encapsulate common or application-specific page
idioms
Provide an HTML-friendly layer of abstraction
Only three data-oriented JSP actions:
<jsp:useBean>
<jsp:setProperty>
<jsp:getProperty>
Why Use Custom Tags?
Custom tags separate presentation from business logic in that
page content is created by page designers while the business
logic's are captured in the form of custom tags.
Now custom tags is not just for business logic but it can
encapsulate other relatively complex functionality such as
complex display, iteration, formatting and so on.
Because custom tags encapsulate business logic, they are
reusable and easier to maintain. In fact, in most cases, you will
use custom tags that are created by someone else.
Because custom tags hide complexity from page authors, it is
easier to author pages. And there are many tools that support
custom tags.
Custom tags provide portable semantics.
Where does custom tags fit in?
This picture shows how custom tags fit into the Web application architecture.
Typically HTTP requests coming from the client are handled by the centralized
controller, which in turn forwards them to JSP pages. The JSP pages then call
server side objects for business logic processing. These server side objects can be
either in the form of Java Beans or custom tags
Custom Tags against JavaBeans
Pros
– Custom tags can manipulate JSP contents
while beans cannot
– Complex operations can be reduced to a
significantly simpler form with custom tags
than beans
Cons
– Custom tags require quite a bit of more
work to set up than do beans
What Can They Do?
Generate content for a JSP page
Access a page’s JavaBeans
Introduce new JavaBeans
Introduce new scripting variables
Any combination of the above
Plus anything else you can do with Java
What Can They Do?
Custom tags have a rich set of features. They can
Be customized via attributes passed from the calling
page.
Pass variables back to the calling page.
Access all the objects available to JSP pages.
Communicate with each other. You can create and
initialize a JavaBeans component, create a public EL
variable that refers to that bean in one tag, and then
use the bean in another tag.
Be nested within one another and communicate via
private variables.
Anatomy of a Custom Tag
Like the standard actions, custom tags
follow XML syntax conventions
<prefix:name attribute=”value”
attribute=”value”/>
or
<prefix:name attribute=”value”
attribute=”value”>
body content
</prefix:name>
Start and End Tags
In XML and JSP
<prefix:name attribute=”value” … />
is equivalent to
<prefix:name attribute=”value” …
”></prefix:name>

Given this equivalence, the model used by
the JSP custom tag API acts as if there is
always a start tag and an end tag.
How Do They Work?
Like most J2EE technologies, there are two
aspects to the development of a custom tag
library.


Individual tags are implemented as Java classes
called Tag Handlers.
An XML file called the Tag Library Descriptor (TLD)
maps a set of tag handlers into a library.
The Java classes and TLD can be deployed
individually or via a JAR file.
How Do They Work?
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.
JSP tag extensions let you create new tags that you
can insert directly into a JavaServer Page just as you
would the built-in tags you learned about in earlier
chapters. The JSP 2.0 specification introduced Simple
Tag Handlers for writing these custom tags.
Three things make up custom tag
architecture
Tag handler class
– Defines tag's behaviour
Tag library descriptor (TLD)
– Maps XML elements to tag handler class
JSP file (user of custom tags)
– Uses tags
To use a custom tag in a JSP page, you must:
* Declare the tag library containing the tag before the usage of any
custom tags from that tag library
* Use custom tags using custom tag syntax in a JSP page
It is assumed that the tag library has been configured and deployed with
individual Web application or globally for all Web applications running on
the server.
Tag Handlers
A tag handler class must implement one of the following
interfaces:



javax.servlet.jsp.tagext.Tag
javax.servlet.jsp.tagext.IterationTag
javax.servlet.jsp.tagext.BodyTag
Usually extends utility class


javax.servlet.jsp.tagext.TagSupport or
javax.servlet.jsp.tagext.BodyTagSupport class
Located in the same directory as servlet class files

/WEB-INF/classes/<package-directory-structure>
A tag handler can optionally implement
javax.servlet.jsp.tagext.TryCatchFinally
Tag attributes are managed as JavaBeans properties (i.e., via
getters and setters)
Tag Library Descriptor
TLD
TLD
TLD
TLD



defines tag syntax
maps tag names to handler classes
constrains tag body content
specifies tag attributes
Attribute names and optional types
Required vs. optional
Compile-time vs. run-time values
TLD specifies tag variables (name, scope,
etc.)
TLD declares tag library validator and lifecycle
event handlers, if any
Tag Library Descriptor
XML file that describes
–
–
–
–
tag name
bodycontent
attributes
tag handler class
Container knows which tag is associated
with which tag handler class via this file
Located
– Usually under WEB-INF directory
Custom location can specified in JSP file
– Via uri attribute of taglib directive
What is Tag Library?
Is a collection of related tags
– Tag(s) can be packaged in a Tag Library
Typically packaged as a jar file containing
– A tag library descriptor (TLD)
• e.g. META-INF/taglib.tld
– *.class files for the tag handler class(es)
– Any additional associated resource(s)
What is Tag Library?
We already talked about tag library. A tag library is a
collection of related tags. It is a customary that you
package related tags into a single tag library.
A tag library is typically packaged as a jar file which
contains TLD file along with tag handler classes and any
related classes.
When a tag library is packaged as a jar file, the TLD file
should reside under META-INF directory and the tag
handler classes should reside under classes directory.
Declaring a tag library
Include taglib directive before tags are
used
Syntax
– <%@ taglib prefix="myprefix" uri=”myuri” %>
– prefix: identifies the tag library
– uri: uniquely identifies the tag library descriptor
(TLD) directly or indirectly
Using Custom Tags
Tags are made available within a JSP
page via the taglib directive:
<%@ taglib uri=”uri” prefix=”prefix” %>
Directive’s uri attribute references the
TLD (established via WAR file’s
web.xml)
Directive’s prefix attribute provides a
local namespace for the TLD’s tags
Steps for implementing, using
& deploying custom tags
The steps you follow in order to implement and deploy custom tags
are relatively straight-forward.
First, you write tag handlers. Under JSP 2.0 architecture, tag
handlers are Java classes.
Second, you write so called tag library descriptor, TLD file, in
short.
Third, you package a set of tag handlers and TLD file into what
is called tag library in either unpacked or packed form.
Then, you write JSP pages that use these tags. Then you deploy
the tag library along with JSP pages.
Now let's talk about 3 things here by using examples - tag
handler, TLD file, and JSP pages.
Example 1- Create "Hello" Tag
JSP tag extensions let you create new tags that you can insert directly into a JavaServer Page
just as you would the built-in tags you learned about earlier. The JSP 2.0 specification
introduced Simple Tag Handlers for writing these custom tags.
To write a custom tag you can simply extend SimpleTagSupport class and override the
doTag() method, where you can place your code to generate content for the tag.
Consider you want to define a custom tag named <ex:Hello> and you want to use it in the
following fashion without a body:
<ex:Hello />
To create a custom JSP tag, you must first create a Java class that acts as a tag handler. So
let us create HelloTag class as follows:
package myTags;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("Hello Custom Tag!");
}
}
Example 1- Create "Hello" Tag
Above code has simple coding where doTag() method takes the current JspContext object
using getJspContext() method and uses it to send "Hello Custom Tag!" to the current
JspWriter object.
Let us compile above class and copy it in a directory available in environment variable
CLASSPATH. Here we have copied it to ROOT\WEB-INF\classes\myTags
Note :You need to include the following to compile:
TOMCAT_HOME/lib/jsp-api.jar
to your CLASSPATH
Finally create following tag library file: <Tomcat-Installation-Directory>webapps\ROOT\WEBINF\custom.tld.
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD</short-name>
<tag>
<name>Hello</name>
<tag-class>myTags.HelloTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
Example 1- Create "Hello" Tag
Now it's time to use above defined custom tag Hello in our JSP program(Hello.jsp) as follows:
Note : Hello.jsp should also be saved in WEB-INF folder
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello/>
</body>
</html>
Start Tomcat server and Try to call above JSP in a browser using:
http://localhost:8080/Hello.jsp
This should produce following result:
Hello Custom Tag!
Accessing the Tag Body:
You can include a message in the body of the tag as you have seen with
standard tags. Consider you want to define a custom tag named <ex:Hello> and
you want to use it in the following fashion with a body:
<ex:Hello>
This is message body
</ex:Hello>
Let us make following changes in above our tag code to process the body of
the tag:
package myTags;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
StringWriter sw = new StringWriter();
public void doTag() throws JspException,
IOException{
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}}
Accessing the Tag Body:
In this case, the output resulting from the invocation is first captured into a
StringWriter before being written to the JspWriter associated with the tag. Now
accordingly we need to change TLD file as follows:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>myTags.HelloTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
Now let us call above tag with proper body as follows:
Accessing the Tag Body:
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello>
This is message body
</ex:Hello>
</body>
</html>
This will produce following result:
This is message body
Custom Tag Attributes:
You can use various attributes along with your custom tags. To accept an attribute
value, a custom tag class needs to implement setter methods, identical to
JavaBean setter methods as shown below:
package myTags;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
private String message;
public void setMessage(String msg) {
this.message = msg;
}
StringWriter sw = new StringWriter();
public void doTag()throws JspException, IOException {
if (message != null) {
/* Use message from attribute */
JspWriter out = getJspContext().getOut();
out.println( message );
} else {
/* use message from the body */
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
}
Custom Tag Attributes:
The attribute's name is "message", so the setter method is setMessage(). Now let
us add this attribute in TLD file using <attribute> element as follows:
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>myTags.HelloTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>message</name>
</attribute>
</tag>
</taglib>
Custom Tag Attributes:
Now let us try following JSP with message attribute as follows:
<%@ taglib prefix="ex" uri="WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello message="This is custom tag" />
</body>
</html>
This will produce following result:
This is custom tag
Hope above example makes sense for you. It would be worth to note that you
can include following properties for an attribute:
Custom Tag Attributes:
Property
Purpose
Name
The name element defines the name of an
attribute. Each attribute name must be unique
for a particular tag.
Required
This specifies if this attribute is required or
optional. It would be false for optional.
Rtexprvalue
Declares if a runtime expression value for a tag
attribute is valid
Type
Defines the Java class-type of this attribute. By
default it is assumed as String
Description
Informational description can be provided.
Fragment
Declares if this attribute value should be treated
as a JspFragment.
Custom Tag Attributes:
Following is the example to specify properties related to an attribute:
.....
<attribute>
<name>attribute_name</name>
<required>false</required>
<type>java.util.Date</type>
<fragment>false</fragment>
</attribute>
.....
If you are using two attributes then you can modify your TLD as follows:
.....
<attribute>
<name>attribute_name1</name>
<required>false</required>
<type>java.util.Boolean</type>
<fragment>false</fragment>
</attribute>
<attribute>
<name>attribute_name2</name>
<required>true</required>
<type>java.util.Date</type>
</attribute>
.....
THANK YOU
Download