830 likes | 939 Views
Object-Oriented Enterprise Application Development. JavaServer Pages Tag Libraries. Topics. During this class we will examine: Benefits of custom tag libraries Tag handlers Tag library descriptors Tags with attributes Complex tags. Introduction. Introduction.
E N D
Object-Oriented Enterprise Application Development JavaServer Pages Tag Libraries
Topics • During this class we will examine: • Benefits of custom tag libraries • Tag handlers • Tag library descriptors • Tags with attributes • Complex tags
Introduction • Custom tags are JSP tags defined by a programmer and used by the content provider. • Custom tags are only available under the 1.1 version of the JSP specification.
Benefits • Custom tags can manipulate the JSP content. • Complex JSP operations can be simplified. • Allows the separation of roles between Java developers and content developers.
Elements • To use a custom tag, you must provide three (3) components: • Define a tag handler class • Define a tag library descriptor • Use the tag within a JSP
Definition • For the JSP to use a new tag, it must have a tag handler class to interpret and respond to the tag. • Each handler must implement the interface javax.servlet.jsp.tagext.Tag. • This can be accomplished by extending the classes TagSupport or BodyTagSupport.
Definition (cont.) • If the tag doesn't have a body or includes the body content as written, then the tag should inherit from the TagSupport class. • The tag on the next slide demonstrates a basic tag handler that provides a simple text insertion.
Sample Code – ExampleTag(1 of 2) • package se452.tags; • import javax.servlet.jsp.*; • import javax.servlet.jsp.tagext.*; • import java.io.*; • public class ExampleTagextends TagSupport { • public int doStartTag() { • try { • JspWriter out = pageContext.getOut(); • out.print("Custom Tag Example"); • }
Sample Code – ExampleTag(2 of 2) • catch (IOException ioe) { • ioe.printStackTrace(); • } • return (SKIP_BODY); • } • }
doStartTag • If the tag doesn't have a body or simply includes the body content, then the tag only needs to override the doStartTag() method. • Since the tag doesn't have a body, this method should return the value SKIP_BODY.
PageContext • The pageContext variable is an object of type PageContext. • The methods you'll most likely use are: • getRequest • getResponse • getServletContext • getSession • getOut
JspWriter • The JspWriter variable is a specific type of PrintWriter object. • It is available to the JSP via the implicit variable, out. • Because it can throw an IOException, the use of the JspWriter should be enclosed within a try…catch block.
Definition • Once the tag handler has been defined, you need to inform the server as to the existence of the tag and the handler to be used to execute that tag. • Such information is stored within a taglibrary descriptor file.
Sample Code – SE452.tld(1 of 2) • <?xml version="1.0" encoding="ISO-8859-1" ?> • <!DOCTYPE taglib • PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> • <!-- a tag library descriptor --> • <taglib> • <!-- after this the default space is "http://java.sun.com/j2ee/dtds/ jsptaglibrary_1_2.dtd" -->
Sample Code – SE452.tld(2 of 2) • <tlibversion>1.0</tlibversion> • <jspversion>1.1</jspversion> • <shortname>SE452</shortname> • <urn></urn> • <info>A tag library for SE452</info> • <tag> • <name>exampleSE452</name> • <tagclass> • se452.tags.ExampleTag • </tagclass> • <info> A simple line of output</info> • </tag> • </taglib>
Tag Library Descriptors • For tags without attributes, there are only four (4) elements of importance within the tag library descriptor file: • name: defines the tag name to which the prefix of the taglib directive will be attached. • tagclass: the fully qualified class name of the tag handler. • info: a brief description of the tag. • bodycontent: for tags without bodies, this value should be EMPTY.
Tag Library Descriptors • Once the tag handler and descriptor have been written, we can use the tag within a JSP. • We need to do two (2) things to make this happen: • Make the JSP aware of the tag library. • Use the specific tag from the library within the JSP itself.
Sample Code – SE452Tag.jsp(1 of 1) • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> • <%@ taglib uri="se452.tld" prefix="se452" %> • <HTML> <HEAD> <TITLE>SE452 Custom Tag JSP</TITLE> • </HEAD> • <BODY> • <H2> • <se452:exampleSE452 /> • </H2> • </BODY> • </HTML>
Justification • It is often useful to add attributes to tags. • For instance, the previous tag could be modified to display a message that is provided as an attribute to the tag itself. • This is what we'll build for our next example.
Sample Code – MessageTag.jsp(1 of 1) • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> • <%@ taglib uri="se452.tld" prefix="se452" %> • <HTML> • <HEAD> • <TITLE>Attribute Tag JSP</TITLE> • </HEAD> • <BODY> • <H2> • <se452:message text="my.message" /> • </H2> <BR> • <H2> <se452:message /> </H2> • </BODY> • </HTML>
Tag Handler Class • If you want a tag to support an attribute, then you need to provide a mutator method on the tag handler to manipulate that attribute. • For instance, I want to have an attribute called text on my tag. So I need to provide a method of the following form: public void setText(String arg) { }
Sample Code – MessageTag(1 of 2) • package se452.tags; • import javax.servlet.jsp.*; • import javax.servlet.jsp.tagext.*; • import java.io.*; • public class MessageTag • extends TagSupport { • private String text = "no.message.defined"; • public String getText() { • return (this.text); • }
Sample Code – MessageTag(2 of 2) • public void setText(String text) { • this.text = text; • } • public int doStartTag() { • try { • JspWriter out = pageContext.getOut(); • out.print( getText() ); • } • catch (IOException ioe) { • ioe.printStackTrace(); • } • return (SKIP_BODY); • } • }
Tag Library Descriptor • We need to define an attribute tag for each attribute: • name: the name of the attribute. • required: true if the attribute must be provided and false (default) otherwise. • rtexprvalue: true if the attribute can be a JSP expression or false (default) if it must be a fixed string.
Sample Code – SE452.tld(1 of 3) • <?xml version="1.0" encoding="ISO-8859-1" ?> • <!DOCTYPE taglib • PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> • <!-- a tag library descriptor --> • <taglib> • <!-- after this the default space is "http://java.sun.com/j2ee/dtds/ jsptaglibrary_1_2.dtd" -->
Sample Code – SE452.tld(2 of 3) • <tlibversion>1.0</tlibversion> • <jspversion>1.1</jspversion> • <shortname>SE452</shortname> • <urn></urn> • <info>A tag library for SE452</info> • <tag> • <name>exampleSE452</name> • <tagclass> • se452.tags.ExampleTag • </tagclass> • <info> A simple line of output</info> • </tag>
Sample Code – SE452.tld(3 of 3) • <tag> • <name>message</name> • <tagclass> • se452.tags.MessageTag • </tagclass> • <info> A simple line of output</info> • <attribute> • <name>text</name> • <required>false</required> • </attribute> • </tag> • </taglib>
Justification • We often want to include body content within a tag. The tags we've done so far have ignored any such content.
Technique(1 of 2) • To keep the body of the tag, the doStartTag() method should return EVAL_BODY_INCLUDE instead of SKIP_BODY. • Technically, if the tag makes use of its body, then you should set the bodycontent attribute in the tag descriptor file to JSP instead of EMPTY.
Technique(2 of 2) • We might want to perform additional work after the body of the tag has been processed. • The doEndTag() method is fired when the closing tag of our custom tag is encountered. • This method returns the value EVAL_PAGE if processing should continue or SKIP_PAGE if JSP processing should stop.
Sample Code – MessageTagBody(1 of 1) • <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> • <%@ taglib uri="se452.tld" prefix="se452" %> • <HTML> • <HEAD> • <TITLE>Attribute Tag JSP</TITLE> • </HEAD> • <BODY> • <se452:messageBody text="message"> • <H3>Just a heading…</H3> • </se452:messageBody> • </BODY> • </HTML>
Sample Code – MessageBodyTag(1 of 2) • package se452.tags; • import javax.servlet.jsp.*; • import javax.servlet.jsp.tagext.*; • import java.io.*; • public class MessageBodyTag • extends TagSupport { • private String text = "no.message.defined"; • public String getText() { • return (this.text); • }
Sample Code – MessageBodyTag(2 of 2) • public void setText(String text) { • this.text = text; • } • public int doStartTag() { • try { • JspWriter out = pageContext.getOut(); • out.print( getText() ); • } • catch (IOException ioe) { • ioe.printStackTrace(); • } • return (EVAL_BODY_INCLUDE); • } • }
Sample Code – SE452.tld(1 of 1) • <tag> • <name>messageBody</name> • <tagclass> • se452.tags.MessageBodyTag • </tagclass> • <info>A simple line of output</info> • <attribute> • <name>text</name> • <required>false</required> • </attribute> • </tag> • </taglib>
Optional Tag Body • It's inefficient to construct a new tag handler to perform essentially the same work as the original. • We might want to conditionally include the body based on some criteria. • We can use a single tag handler to either process or skip the body by simply changing the return value at run-time.
Justification • We might want to manipulate the contents of the tag body itself perhaps to add or modify the content.
Technique • In this case, the TagSupport base class is insufficient. Instead, we must inherit from the BodyTagSupport class which itself extends the TagSupport class.
BodyTagSupport Class • The major methods provided by the BodyTagSupport class are: • doAfterBody: a method we override to handle the manipulation of the tag's body. • getBodyContent: returns an object of type BodyContent that encapsulates information about the content of the tag body.
BodyContent Class • The key methods provided by the BodyContent class are: • getEnclosingWriter: returns the JspWriter object used by the doStartTag() and doEndTag() methods. • getReader: returns a Reader that can read the tag's body. • getString: returns a String containing the entire tag body.
Custom Loop Tag(1 of 2) • In the 0.92 version of the JSP specification, there was a LOOP tag that could be used to iterate a specific number of times. • This tag was removed as of version 1.0 of the JSP specification since Java could be embedded within the JSP anyway. • It's such a useful construct, that I want to resurrect it by creating a custom LoopTag tag with a reps attribute.
Sample Code – LoopTag(1 of 3) • package se452.tags; • import javax.servlet.jsp.*; • import javax.servlet.jsp.tagext.*; • import java.io.*; • public class LoopTagextends BodyTagSupport { • private int reps = 1; • public int getReps() { • return (this.reps); • }
Sample Code – LoopTag(2 of 3) • public void setReps(String reps) { • try { • this.reps = Integer.parseInt(reps); • } • catch (NumberFormatException nfe) { • } • }