Object-Oriented Enterprise Application Development

Preview:

DESCRIPTION

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. - PowerPoint PPT Presentation

Citation preview

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

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

Tag Handlers

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)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class ExampleTagextends TagSupport {

6. public int doStartTag() {7. try {8. JspWriter out =

pageContext.getOut();9. out.print("Custom Tag Example");10. }

Sample Code – ExampleTag(2 of 2)11. catch (IOException ioe) {12. ioe.printStackTrace();13. }14. return (SKIP_BODY);15. }16. }

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.

Tag Library Descriptor

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 tag library descriptor file.

Sample Code – SE452.tld(1 of 2)1. <?xml version="1.0" encoding="ISO-8859-1" ?>2. <!DOCTYPE taglib3. PUBLIC "-//Sun Microsystems, Inc.//DTD

JSP Tag Library1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

4. <!-- a tag library descriptor -->

5. <taglib>6. <!-- after this the default space is

"http://java.sun.com/j2ee/dtds/ jsptaglibrary_1_2.dtd" -->

Sample Code – SE452.tld(2 of 2)7. <tlibversion>1.0</tlibversion>8. <jspversion>1.1</jspversion>9. <shortname>SE452</shortname>10. <urn></urn>11. <info>A tag library for SE452</info>

12. <tag>13. <name>exampleSE452</name>14. <tagclass>15. se452.tags.ExampleTag16. </tagclass>17. <info> A simple line of output</info>18. </tag> 19. </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.

JavaServer Pages

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)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>

<HEAD> <TITLE>SE452 Custom Tag JSP</TITLE>

4. </HEAD>5. <BODY>6. <H2>7. <se452:exampleSE452 />8. </H2>9. </BODY>10. </HTML>

Tags With Attributes

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)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>4. <HEAD>5. <TITLE>Attribute Tag JSP</TITLE>6. </HEAD>7. <BODY>8. <H2>9. <se452:message text="my.message" />10. </H2> <BR>11. <H2> <se452:message /> </H2>12. </BODY>13. </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)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class MessageTag6. extends TagSupport {7. private String text =

"no.message.defined";

8. public String getText() {9. return (this.text);10. }

Sample Code – MessageTag(2 of 2)11. public void setText(String text) {12. this.text = text;13. }14. public int doStartTag() {15. try {16. JspWriter out =

pageContext.getOut();17. out.print( getText() );18. }19. catch (IOException ioe) {20. ioe.printStackTrace();21. }22. return (SKIP_BODY);23. }24. }

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)1. <?xml version="1.0" encoding="ISO-8859-1" ?>2. <!DOCTYPE taglib3. PUBLIC "-//Sun Microsystems, Inc.//DTD

JSP Tag Library1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

4. <!-- a tag library descriptor -->

5. <taglib>6. <!-- after this the default space is

"http://java.sun.com/j2ee/dtds/ jsptaglibrary_1_2.dtd" -->

Sample Code – SE452.tld(2 of 3)7. <tlibversion>1.0</tlibversion>8. <jspversion>1.1</jspversion>9. <shortname>SE452</shortname>10. <urn></urn>11. <info>A tag library for SE452</info>

12. <tag>13. <name>exampleSE452</name>14. <tagclass>15. se452.tags.ExampleTag16. </tagclass>17. <info> A simple line of output</info>18. </tag>

Sample Code – SE452.tld(3 of 3)19. <tag>20. <name>message</name>21. <tagclass>22. se452.tags.MessageTag23. </tagclass>24. <info> A simple line of output</info>25. <attribute>26. <name>text</name>27. <required>false</required>28. </attribute>29. </tag> 30. </taglib>

Tags With Bodies

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)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>4. <HEAD>5. <TITLE>Attribute Tag JSP</TITLE>6. </HEAD>7. <BODY>8. <se452:messageBody text="message">9. <H3>Just a heading…</H3>10. </se452:messageBody>11. </BODY>12. </HTML>

Sample Code – MessageBodyTag(1 of 2)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class MessageBodyTag6. extends TagSupport {7. private String text =

"no.message.defined";

8. public String getText() {9. return (this.text);10. }

Sample Code – MessageBodyTag(2 of 2)11. public void setText(String text) {12. this.text = text;13. }14. public int doStartTag() {15. try {16. JspWriter out =

pageContext.getOut();17. out.print( getText() );18. }19. catch (IOException ioe) {20. ioe.printStackTrace();21. }22. return (EVAL_BODY_INCLUDE);23. }24. }

Sample Code – SE452.tld(1 of 1)1. <tag>2. <name>messageBody</name>3. <tagclass>4. se452.tags.MessageBodyTag5. </tagclass>6. <info>A simple line of output</info>7. <attribute>8. <name>text</name>9. <required>false</required>10. </attribute>11. </tag> 12. </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.

Manipulating Tag Bodies

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.

Looping

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)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class LoopTagextends BodyTagSupport {

6. private int reps = 1;

7. public int getReps() {8. return (this.reps);9. }

Sample Code – LoopTag(2 of 3)10. public void setReps(String reps) {11. try {12. this.reps =

Integer.parseInt(reps);13. }14. catch (NumberFormatException nfe) {15. }16. }

Sample Code – LoopTag(3 of 3)17. public int doAfterBody() {18. if (reps-- >= 1) {19. BodyContent body =getBodyContent();20. try {21. JspWriter out =

body.getEnclosingWriter();22. out.println(body.getString());23. body.clearBody();24. }25. catch (IOException ioe) {26. ioe.printStackTrace();27. }28. return ( EVAL_BODY_TAG );29. }30. return ( SKIP_BODY );31. }32. }

Custom Loop Tag(2 of 2)

Notice that since there isn't any custom content to be generated when the tag is first encountered, I don't provide a doStartTag() method.

Sample Code – LoopTag (rev.)(1 of 1)1. public int doStartTag() {2. try {3. JspWriter out = pageContext.getOut();4. out.print( "Looping " + getReps() +

" times\n" );5. }6. catch (IOException ioe) {7. ioe.printStackTrace();8. }9. return ( EVAL_BODY_TAG );10. }

Sample Code – SE452.tld(1 of 1)1. <tag>2. <name>loop</name>3. <tagclass>4. se452.tags.LoopTag5. </tagclass>6. <info>Loops</info>7. <attribute>8. <name>reps</name>9. <required>false</required>10. <rtexprvalue>true</rtexprvalue>11. </attribute>12. </tag> 13. </taglib>

Sample Code – LoopTag.jsp(1 of 1)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>4. <HEAD>5. <TITLE>SE452 Custom Loop Tag</TITLE>6. </HEAD>7. <BODY>8. <se452:loop reps="5">9. <%= new java.util.Date() %>10. </se452:loop>11. </BODY>12. </HTML>

Nested Tags

Nesting Tags

There are two (2) key things to know about nested tags:

Use the findAncestorWithClass() method to locate the immediate ancestor of a nested tag.

If an inner tag needs data from its enclosing tag, then it's the enclosing tag's responsibility to provide a mechanism for the nested tag to use to store and retrieve that data,

Custom If…Then…Else Tag(1 of 2)

In the 0.92 version of the JSP specification, there were INCLUDEIF and EXCLUDEIF tags that were used for conditional content.

These 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 custom IF…THEN…ELSE tags.

Custom If…Then…Else Tag(2 of 2)

This example is taken from your book and hasn't been modified very much.

We will discuss the various tag handler classes and their associated tag library definitions needed to implement a conditional tag.

Tag Handlers

For this custom tag, we'll need the following tag handlers:IfTag

IfConditionTag

IfThenTag

IfElseTag

Sample Code – IfTag(1 of 3)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class IfTag extends TagSupport {

6. private boolean condition;7. private boolean hasCondition = false;

Sample Code – IfTag(2 of 3)8. public void

setCondition(boolean condition) {9. this.condition = condition;10. this.hasCondition = true;11. }

12. public boolean getCondition() {13. return ( this.condition );14. }

Sample Code – IfTag(3 of 3)15. public void

setHasCondition(boolean flag) {16. this.hasCondition = flag;17. }

18. public boolean hasCondition() {19. return ( hasCondition );20. }

21. public int doStartTag() {22. return ( EVAL_BODY_INCLUDE );23. }24. }

Sample Code – IfConditionTag(1 of 2)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class IfConditionTagextends BodyTagSupport {

6. public int doStartTag() throws JspTagException {

7. IfTag parent = (IfTag) findAncestorWithClass(this, IfTag.class);

Sample Code – IfConditionTag(2 of 2)8. if (parent == null) {9. throw new JspTagException(

"condition not inside if");10. }11. return ( EVAL_BODY_TAG );12. }13. public int doAfterBody() {14. IfTag parent = (IfTag)

findAncestorWithClass(this, IfTag.class);

15. String bodyString = getBodyContent().getString();

16. parent.setCondition(bodyString. trim().equals("true"));

17. return ( SKIP_BODY );18. }19. }

Sample Code – IfThenTag(1 of 4)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class IfThenTagextends BodyTagSupport {

6. public int doStartTag() throws JspTagException {

7. IfTag parent = (IfTag) findAncestorWithClass(this, IfTag.class);

Sample Code – IfThenTag(2 of 4)8. if (parent == null) {9. throw new JspTagException(

"then not inside if");10. }11. else if ( !parent.hasCondition() ) {12. throw new JspTagException(

"no condition before then");13. }14. return ( EVAL_BODY_TAG );15. }

Sample Code – IfThenTag(3 of 4)16. public int doAfterBody() {17. IfTag parent = (IfTag)

findAncestorWithClass(this, IfTag.class);

18. if ( parent.getCondition() ) {19. try {20. BodyContent body =

getBodyContent();21. JspWriter out =

body.getEnclosingWriter();22. out.print(body.getString());23. }

Sample Code – IfThenTag(4 of 4)24. catch (IOException ioe) {25. ioe.printStackTrace();26. }27. }28. return ( SKIP_BODY );29. }30. }

Sample Code – IfElseTag(1 of 4)1. package se452.tags;

2. import javax.servlet.jsp.*;3. import javax.servlet.jsp.tagext.*;4. import java.io.*;

5. public class IfElseTagextends BodyTagSupport {

6. public int doStartTag() throws JspTagException {

7. IfTag parent = (IfTag) findAncestorWithClass(this, IfTag.class);

Sample Code – IfElseTag(2 of 4)8. if (parent == null) {9. throw new JspTagException(

"then not inside if");10. }11. else if ( !parent.hasCondition() ) {12. throw new JspTagException(

"no condition before else");13. }14. return ( EVAL_BODY_TAG );15. }

Sample Code – IfElseTag(3 of 4)16. public int doAfterBody() {17. IfTag parent = (IfTag)

findAncestorWithClass(this, IfTag.class);

18. if ( !parent.getCondition() ) {19. try {20. BodyContent body =

getBodyContent();21. JspWriter out =

body.getEnclosingWriter();22. out.print(body.getString());23. }

Sample Code – IfElseTag(4 of 4)24. catch (IOException ioe) {25. ioe.printStackTrace();26. }27. }28. return ( SKIP_BODY );29. }30. }

Sample Code – SE452.tld(1 of 2)1. <tag>2. <name>if</name>3. <tagclass>se452.tags.IfTag</tagclass>4. <info> if tag </info>5. </tag>

6. <tag>7. <name>condition</name>8. <tagclass>9. se452.tags.IfConditionTag10. </tagclass>11. <info> condition tag </info>12. </tag>

Sample Code – SE452.tld(2 of 2)13. <tag>14. <name>then</name>15. <tagclass>16. se452.tags.IfThenTag17. </tagclass>18. <info> then tag </info>19. </tag>

20. <tag>21. <name>else</name>22. <tagclass>23. se452.tags.IfElseTag24. </tagclass>25. <info> else tag </info>26. </tag>

Sample Code – IfTag.jsp(1 of 2)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>4. <HEAD>5. <TITLE> If...Then...Else Tag </TITLE>6. </HEAD>7. <BODY>8. <H2>If Tag Samples</H2>

Sample Code – IfTag.jsp(2 of 2)9. <se452:if>10. <se452:condition>11. true12. </se452:condition>13. <se452:then>14. condition is true15. </se452:then>16. <se452:else>17. condition is false18. </se452:else>19. </se452:if>20. </BODY>21. </HTML>

Sample Code – NestedIfTag.jsp(1 of 3)1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML

4.0 Transitional//EN">2. <%@ taglib uri="se452.tld"

prefix="se452" %>3. <HTML>4. <HEAD>5. <TITLE>If...Then...Else JSP</TITLE>6. </HEAD>7. <BODY>8. <H2>If Tag Samples</H2>9. <se452:if>10. <se452:condition>11. false12. </se452:condition>

Sample Code – NestedIfTag.jsp(2 of 3)13. <se452:then>14. <se452:if>15. <se452:condition>16. false17. </se452:condition>18. <se452:then>19. inner true:false20. </se452:then>21. <se452:else>22. inner true:true23. </se452:else>24. </se452:if>25. </se452:then>

Sample Code – NestedIfTag.jsp(3 of 3)26. <se452:else>27. outer false28. </se452:else>29. </se452:if>30. </BODY>31. </HTML>

Review

During this class we have discussed:

Benefits of custom tag libraries

Tag handlers

Tag library descriptors

Tags with attributes

Complex tags

Resources

Core Servlets and JavaServer PagesMarty Hall, Prentice-Hall, Inc., 2000.ISBN: 0-13-089340-4

Coming Attractions

Next week we'll discuss JavaBeans and how they can be integrated into the presentation layer.

Please read Chapter 13 in your text.

Recommended