Beruflich Dokumente
Kultur Dokumente
by Sue Spielman
04/19/2001
If you've ever had the opportunity to build a web application using Java technology,
chances are you have used Java Server Pages (JSP) for content display. JSP is the
technology that helps separate the front end presentation from the middle and backend
tiers. The custom tag library is a powerful feature of JSP v1.1 that aids in that separation.
This technology is valuable to anyone who is building production-quality web applications,
and it is very applicable in today's market.
Custom tag libraries allow the Java programmer to write code that provides data access
and other services, and they make those features available to the JSP author in a simple to
use XML-like fashion. An action in a web application -- for example, gaining database
access -- can be customized by using a custom tag in a JSP page. The JSP author doesn't
have to understand the underlying detail to complete the action. In short, a tag library is a
collection of custom actions presented as tags.
Custom tags have many features that make them attractive to use from any JSP. Custom
tags can
• be customized via attributes passed from the calling page, either staticly or
determined at runtime;
• have access to all the objects available to JSP pages including request, response,
in and out;
• 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;
and
• encapsulate both simple and complex behaviors in an easy to use syntax and
greatly simplify the readability of JSP pages.
Let's look at what makes up a tag library and build one step by step.
There are two types of components for a tag library: the tag library descriptor file and the
tag handlers. With these a JSP is able to use tags contained in the library within its page.
Then each tag contained in the library is described. There can be one or many tags per
library. There is only one TLD element required for all tags, and that is the one used to
specify a tag handler's class: <tagclass>classname</tagclass>
There are various other elements used to describe tags. Which elements a tag uses will
depend on how the tag is implemented in the handler. We'll get to that discussion in the
section below.
If a tag has attributes associated with it, then each attribute must be described within the
<tag> element. If an attribute is required by a tag, <required> is set to "true" or "yes".
To allow a runtime expression value to be used by the tag, the <rtexpvalue> is set to
"true" or "yes". For each attribute of a tag, a Bean-like getter/setter method needs to be
defined in the handler class. It's also possible to define scripting variables for use in tags.
This is accomplished using a TagExtraInfo class and will be discussed in the tag handler
section. If a TagExtraInfo is to be used, the class must be defined using the
<teiclass>classname<teiclass> within the tag definition.
A more advanced feature is the use of scripting variables. Typically an attribute is passed
to the tag that contains the ID of the object to be used. The usual operation is that the tag
handler retrieves a scripting variable value object using
pageContext.getAttribute(name), performs some processing on it, and then sets the
scripting variable's value using the pageContext.setAttribute(name, object). In
addition to setting the value of the variable within the tag handler, you must define a class
derived from TagExtraInfo that provides information to the JSP container about the
nature of the variable. That class is then listed in the <teiclass> attribute of the tag.
The Java code for the tag defined in the oreillySample.tld file would look like
package oreilly.examples
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* This is a simple tag example to show how content is added to the
* output stream when a tag is encountered in a JSP page.
*/
public class Hello extends TagSupport {
private String name=null;
/**
* Getter/Setter for the attribute name as defined in the tld
file
* for this tag
*/
public void setName(String value){
name = value;
}
The JSP
Once your TLD and tag handlers are created, you can begin accessing the tags in your JSP.
You declare that a JSP page will use tags defined in a tag library by including a taglib
directive in the page before any custom tag is used. The prefix attribute is a shortcut to
referencing the library throughout the page.
Sample Hello.jsp:
The HTML source output from this JSP would look like:
<html>
<head>
<title>Your Standard Hello World Demo</title>
</head>
<body bgcolor="#ffffff">
<hr />
<table border="1">
<tr><td> Hello Sue </td></tr>
</table>
<hr />
</body>
</html>
You can see how the tag was evaluated and the contents of the tag inserted into the
output stream.
If you wanted to add functionality to our tag to make it more flexible, say to evaluate a
body a certain number of times and make the name attribute evaluated at runtime, you
can do so fairly easily with a few changes. First you would make the following changes to
the TLD file. The tag definition would look like
<tag>
<name>hello</name>
<tagclass>oreilly.examples.Hello </tagclass>
<!-- Allow for a body to be included for this tag -->
<bodycontent>JSP</bodycontent>
<info>
This is a simple hello tag.
</info>
</tag>
Then you must alter the handler class by extending TagBodySupport and implementing
the body methods if you wanted different behavior from that provided in the base class
implementation. The handler class would now look like
/**
* Getter/Setter for the attribute name as defined in the tld
file
* for this tag
*/
public void setName(String value){
name = value;
}
Now let's make the simple changes in the JSP file. Our sample Hello.jsp looks like
<html>
<head>
<title>Your Standard Hello World Demo</title>
</head>
<body bgcolor="#ffffff">
<hr />
<sample:hello name="<%= userName %>" iterations="2">
<tr><td><b>Have a nice day</b></td></tr>
</sample:hello>
<hr />
</body>
</html>
If our JSP page was called like hello.jsp?NAME=Sue our output would look like
<html>
<head>
<title>Your Standard Hello World Demo</title>
</head>
<body bgcolor="#ffffff">
<hr />
<table border="1">
<tr><td> Hello Sue </td></tr>
<tr><td><b>Have a nice day</b></td></tr>
<tr><td><b>Have a nice day</b></td></tr>
</table>
<hr />
</body>
</html>
This simple example is but a small glimpse at the power of custom tag libraries. We
examined how to create and use a simple tag library and then easily extend its
functionality. The next article will examine some of the advanced features of tags,
including defining scripting variables and cooperating tags. It will also go through working
examples of each.
Sue Spielman is an associate editor for ONJava.com, covering JSP and Servlets
technologies. She is also President and Senior Consulting Engineer for Switchback
Software LLC.
• can anyone solve my doubt
2007-11-28 09:36:45 laxmi001 [Reply | View]
can i use like this i.e connect.java one class and update.java is another class if i call the
class in the jsp as enclosed above jsp will it recognise tags(ie attribute in the tld),will it
forwards the request to the update class.
When iam trying its not forwarding just it executing only connect class, and its not
forwarding to the update class.
can use like this ie connect one class and update is another class if i call the class in the
jsp as enclosed above will it recognise tags(ie attribute in the tld),will it forwards the
request to the update class.
<attribute>
<name>adminPwd</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
• error in tld
2007-09-27 03:51:54 sathya_k_83 [Reply | View]
<attribute>
<name>adminId</name>
<required>false</required>
<rtexpvalue>false</rtexpvalue>
</attribute>
if the required and rtexpvalue are tag are inserted , the eclipse SDK is showing error
--------------------------------------------------------------------------------
message
description The server encountered an internal error () that prevented it from fulfilling
this request.
exception
---- JSP
<%@ page session="false" %>
<%@ taglib uri="oreillySample" prefix="sample"%>
<html>
<head>
<title>Your Standard Hello World Demo</title>
</head>
<body bgcolor="#ffffff">
<hr />
<sample:hello name="Sue"/>
<hr />
</body>
</html>
--- TLD
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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>
<shortname>oreillySample</shortname>
<info>OReilly Sample Tag library</info>
<tag>
<name>Hello</name>
<tagclass>oreilly.examples.HelloTag</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
--- WEB.XML
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>
Tag Lib
</display-name>
<welcome-file-list>
<welcome-file>Hello.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>oreillySample</taglib-uri>
<taglib-location>/WEB-INF/tlds/oreillySample.tld</taglib-location>
</taglib>
</web-app>
--- HelloTag.java
package oreilly.examples;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* This is a simple tag example to show how content is added to the
* output stream when a tag is encountered in a JSP page.
*/
public class HelloTag extends TagSupport {
private String name=null;
/**
* Getter/Setter for the attribute name as defined in the tld file
* for this tag
*/
public void setName(String value){
name = value;
}
/**
* doStartTag is called by the JSP container when the tag is encountered
*/
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.println("<table border=1>");
if (name != null)
out.println("<tr><td> HelloTag " + name + " </td></tr>");
else
out.println("<tr><td> HelloTag World </td></tr>");
} catch (Exception ex) {
throw new Error("All is not well in the world.");
}
// Must return SKIP_BODY because we are not supporting a body for this
// tag.
return SKIP_BODY;
}
/**
* doEndTag is called by the JSP container when the tag is closed
*/
public int doEndTag(){
try {
JspWriter out = pageContext.getOut();
out.println("</table>");
} catch (Exception ex){
throw new Error("All is not well in the world.");
}
return EVAL_PAGE;
}
}
Ch04
Hello.jsp
-> WEB-INF
web.xml
-->src\oreilly.examples.HelloTag.java
-->classes\oreilly.examples.HelloTag.class
-->tlds\oreillySample.tld
xml parsing error in file.document root element taglib must match document type
element "null"
Error :
<sample:hello name="Sue"/>
Resolved :
<sample:Hello name="Sue"/>
hai,
i'm new to struts and was going through the examples,with iterations but
it is giving me some errors...In the example no method is written for getBodyContent();
I'm attaching the exception which came...
org.apache.jasper.JasperException: /Hello.jsp(13,2) jasper.error.bad.bodycontent.type
org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:39)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:409)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:90)
org.apache.jasper.compiler.Parser.parseBody(Parser.java:1809)
org.apache.jasper.compiler.Parser.parseOptionalBody(Parser.java:1060)
org.apache.jasper.compiler.Parser.parseCustomTag(Parser.java:1367)
org.apache.jasper.compiler.Parser.parseElements(Parser.java:1560)
org.apache.jasper.compiler.Parser.parse(Parser.java:126)
org.apache.jasper.compiler.ParserController.doParse(ParserController.java:220)
org.apache.jasper.compiler.ParserController.parse(ParserController.java:101)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:203)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:470)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:451)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:439)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:511)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:295)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
RachelMary
Dear Sir/Madam,
I had read the article on the website about JSP Custom Tag Library. It's really very
good.
But during that I found one error in the sample code.
I request to u check and make it corrected.
The exaple is at the url.
http://www.onjava.com/pub/a/onjava/2000/12/15/jsp_custom_tags.html
}
must have to return integer but in code the return statement is missing.
Thanking you.
Amit Jadhav
hi all i am amature java programmer, i am trying to create a new intranet mail server i
have to my knowledge done everything correct all modules or working properly.I am in
the event of integrating the project at this juncture in my main jsp file which has a
customtag. this customtag calls a ejb and which in returns a boolean value which
indicates the authenticity of the user.with this boolean i need to redirect the user to the
next page. i need to get the value from the customtag and need to perform the check. if
any one could help me in that regard it would be of great help to me.my mail id is
prabhu_studs@yahoo.com please feel free to contact me.
• doEndTag
2004-07-08 12:00:38 jkronz [Reply | View]
What is the int this method is supposed to return? the author never has a return
statement in his code, and therefore it never compiles..
o doEndTag
2005-06-25 17:01:32 MurderCityWeb [Reply | View]
return EVAL_PAGE;
http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/tagext/TagSupport.
html#doEndTag()
o doEndTag
2005-04-18 05:11:28 madhukumar [Reply | View]
What is the int this method is supposed to return? the author never has a return
statement in his code, and therefore it never compiles..
I'm trying to run the example but I cant understant how they need be installed.
The TLD file doesn't get compiled separately. The container uses it the way it is. It
just needs to be in the WEB-INF directory.
Specifically, the class file containing the tag library handler needs to go in WEB-
INF/classes. (At least, that's right for Jetty, which is what I use. Should be the
same for Tomcat.)
I use Apache to serve HTML/PHP. I am using Jetty to serve JSP files and servlets
from the same directory as the HTML and PHP files. In my case, the example
given by Sue required me to put the TLD file in the top directory of the website,
not under WEB-INF. So it depends on what your specific setup is.
I made the corrections posted by sjsobol, moved the TLD file to the top
level(was previously getting an error as well), but still can't seem to get this
to work.
I am getting error:
org.apache.jasper.JasperException: /hello.jsp(7,16) Unable to load class hello
hello.jsp
<%@ taglib uri="/oreillySample.tld" prefix="sample" %>
<html>
<head>
<title>Your Standard Hello World Demo</title>
</head>
<body bgcolor="#ffffff">
<hr />
<sample:hello name="Sue"/>
<hr />
</body>
</html>
I am working through one of James Goodwill's examples and can't, for the life of me,
figure out EXACTLY what goes where:
at
org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:130
)
at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:293)
at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:340)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:352)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:474)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:184)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:295)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:43
2)
at
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:356)
at login.doPost(login.java:48)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.ja
va:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:260
)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2415)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:643)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:641)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:172)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:641)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at
org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(St
andardPipeline.java:643)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:223)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:432)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(
Http11Protocol.java:386)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:534)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:530)
at java.lang.Thread.run(Thread.java:536)
Any thoughts?
J
Hi
Did you solve your problem. Because I've the same problem error at line -1 in jsp
file: null
and I don't know how to solve it.
JSP
---
JAVA
----
package com.ml.gmi.edsi.ipro.client.action.testClasses;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* This is a simple tag example to show how content is added to the
* output stream when a tag is encountered in a JSP page.
*/
public class Hello extends TagSupport {
private String name=null;
/**
* Getter/Setter for the attribute name as defined in the tld file
* for this tag
*/
public void setName(String value){
name = value;
}
/**
* doStartTag is called by the JSP container when the tag is encountered
*/
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.println("<table border=1>");
if (name != null)
out.println("<tr><td> Hello " + name + " </td></tr>");
else
out.println("<tr><td> Hello World </td></tr>");
} catch (Exception ex) {
throw new Error("All is not well in the world.");
}
// Must return SKIP_BODY because we are not supporting a body for this
// tag.
return SKIP_BODY;
}
/**
* doEndTag is called by the JSP container when the tag is closed
*/
public int doEndTag(){
try {
JspWriter out = pageContext.getOut();
out.println("</table>");
} catch (Exception ex){
throw new Error("All is not well in the world.");
}
return EVAL_PAGE;
}
}
TLD:
---
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>oreillySamples</shortname>
<info>OReilly Sample Tag library</info>
<tag>
<name>hello</name>
<tagclass>com.ml.gmi.edsi.ipro.client.action.testClasses.Hello</tagclass>
<bodycontent>empty</bodycontent>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
WEB.XML
--------
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<taglib>
<taglib-uri>/WEB-INF/oreillySample.tld</taglib-uri>
<taglib-location>/WEB-INF/oreillySample.tld</taglib-location>
</taglib>
</web-app>
This is rediculous, there are so many problems with the associated code maybe we
should consider making this example a working one.
Page URL:
http://www.onjava.com/pub/a/onjava/2000/12/15/jsp_custom_tags.html?page=2
The attribute 'name' for custom tag 'hello' on line '12' of page '/Hello.jsp' has a request
time expression as an attribute value but is not declared to accept them in its TLD.
Instead of:
<rtexpvalue>true</rtexpvalue>
should be:
<rtexprvalue>true</rtexprvalue>
libor p.
Looks like the form handler on this site doesn't replace html with special characters, so
let me give it another try -- in doStartTag, on the first out.println, the escape character
for the first quote (") should be put before the quote, not after the quote.
mike
• Typo in DoStartTag?
2001-05-30 15:34:14 mdwchang [Reply | View]
I believe there is a typo in the first out.println statement -- I'm not sure if this is
causing the error the previous poster spoke about.
hi,
Thank U
Regards
Prakasam
hi,
Thank U
Regards
Prakasam
I get the following error message in the browser when I run this:
Parse Error in the tag library descriptor: Element "web-app" does not allow "servlet"
here.
at
org.apache.jasper.compiler.JspParseEventListener.handleDirective(JspParseEventListener
.java:672)
at
org.apache.jasper.compiler.DelegatingListener.handleDirective(DelegatingListener.java:1
16)
at org.apache.jasper.compiler.Parser$Directive.accept(Parser.java:215)
at org.apache.jasper.compiler.Parser.parse(Parser.java:1073)
at org.apache.jasper.compiler.Parser.parse(Parser.java:1038)
at org.apache.jasper.compiler.Parser.parse(Parser.java:1034)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:182)
at org.apache.jasper.runtime.JspServlet.loadJSP(JspServlet.java:413)
at
org.apache.jasper.runtime.JspServlet$JspServletWrapper.loadIfNecessary(JspServlet.jav
a:149)
at org.apache.jasper.runtime.JspServlet$JspServletWrapper.service(JspServlet.java:161)
at org.apache.jasper.runtime.JspServlet.serviceJspFile(JspServlet.java:261)
at org.apache.jasper.runtime.JspServlet.service(JspServlet.java:369)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at org.apache.tomcat.core.ServletWrapper.handleRequest(ServletWrapper.java:503)
at org.apache.tomcat.core.ContextManager.service(ContextManager.java:559)
at
org.apache.tomcat.service.connector.Ajp12ConnectionHandler.processConnection(Ajp12
ConnectionHandler.java:156)
at org.apache.tomcat.service.TcpConnectionThread.run(SimpleTcpEndpoint.java:338)
at java.lang.Thread.run(Thread.java:475)
In the first example, the doEndTag of the Hello class is missing the return statement. I
assume it was meant to be something like the following:
return EVAL_PAGE;
In the first example, the doEndTag of the Hello class is missing the return statement. I
assume it was meant to be something like the following:
return EVAL_PAGE;