JSP Template

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12
At a glance
Powered by AI
The key takeaways are that JSP templates can be used to encapsulate webpage layout and encourage modular design. Templates allow content to be included dynamically and minimize the impact of layout changes.

The article aims to address the problem that JSP does not provide direct support for encapsulating layout. Webpages with identical formats usually replicate layout code, making changes difficult.

The article proposes using templates to solve the layout problem. Templates are JSP files that include parameterized content. This allows layout to be included in addition to content, minimizing the impact of layout changes.

Article

JSP Templates

Articles Index
Use JSP Templates To Encapsulate Webpage Layout And Encourage Modular Design
By David Geary; Reprinted from JavaWorld
November 2000

Window toolkits typically provide a layout mechanism that positions widgets in a container. For example, AWT a

Although Web development tools are rapidly progressing, they still lag behind most graphical user interface (GU

Because layout undergoes many changes over the course of development, it's important to encapsulate that functi

JSP does not provide direct support for encapsulating layout, so Webpages with identical formats usually replicat

Figure 1. Webpage layout


Click on thumbnail to view full image (22 KB)

The layout of the page shown in Figure 1 is implemented with HTML table tags:
Example 1. Including content
<html><head><title>JSPTemplates</title></head>
<bodybackground='graphics/background.jpg'>
<table>
<trvalign='top'><td><%@includefile='sidebar.html'%></td>
<td><table>
<tr><td><%@includefile='header.html'%></td></tr>
<tr><td><%@includefile='introduction.html'%></td></tr>
<tr><td><%@includefile='footer.html'%></td></tr>
</table>
</td>
</tr>

</table>
</body></html>

In the example listed above, content is included with the JSP include directive, which allows the content of the

To minimize the impact of layout changes, we need a mechanism for including layout in addition to content; that

Using templates
Templates are JSP files that include parameterized content. The templates discussed in this article are implemente

Example 2.a. A template


<%@tagliburi='/WEBINF/tlds/template.tld'prefix='template'%>
<html><head><title><template:getname='title'/></title></head>
<bodybackground='graphics/background.jpg'>
<table>
<trvalign='top'><td><template:getname='sidebar'/></td>
<td><table>
<tr><td><template:getname='header'/></td></tr>
<tr><td><template:getname='content'/></td></tr>
<tr><td><template:getname='footer'/></td></tr>
</table>
</td>
</tr>
</table>
</body></html>

Example 2.a is nearly identical to Example 1, except we use template:get instead of the include directive. Let
template:get

retrieves a Java bean with the specified name from request scope. The bean contains the URI (Un

template:put

puts the beans in request scope that are subsequently retrieved by template:get. The template is

Example 2.b. Using the template from Example 2.a


<%@tagliburi='/WEBINF/tlds/template.tld'prefix='template'%>
<template:inserttemplate='/articleTemplate.jsp'>
<template:putname='title'content='Templates'direct='true'/>
<template:putname='header'content='/header.html'/>
<template:putname='sidebar'content='/sidebar.jsp'/>
<template:putname='content'content='/introduction.html'/>
<template:putname='footer'content='/footer.html'/>
</template:insert>

The insert start tag specifies the template to be included, in this case the template listed in Example 2.a. Each p

A direct attribute can be specified for template:put; if direct is set to true, the content associated with the t

Websites containing multiple pages with identical formats have one template, such as the one listed in Example 2
Another benefit of templates and including content in general is modular design. For example, the JSP file listed
Example 2.c. header.html

<table>
<tr>
<td><imgsrc='/developer/technicalArticles/javaserverpages/jsp_templates/graphics/ja
<td><imgsrc='/developer/technicalArticles/javaserverpages/jsp_templates/graphics/te
</tr>
</table><hr>

Because header.html is included content, it does not have to be replicated among pages that display a header. A

Note: JSP provides two ways to include content: statically, with the include directive, and dynamically, with the

Like the JSP include action, templates include content dynamically. So, although the JSP pages in Example 1 an

Optional content
All template content is optional, which makes a single template useful to more Webpages. For example, Figure 2

Figure 2.a. A login form


Click on thumbnail to view full image (24 KB)

Figure 2.b. An inventory page


Click on thumbnail to view full image (42 KB)

Below, you'll find the template shared by the login and inventory pages:

<%@tagliburi='template.tld'prefix='template'%>
...
<tablewidth='670'>
<tr><tdwidth='60'></td>
<td><template:getname='header'/></td></tr>
<tr><tdwidth='60'></td>
<td><template:getname='maincontent'/></td></tr>
<tr><tdwidth='60'></td>
<td><template:getname='editPanel'/></td></tr>
<tr><tdwidth='60'></td>
<td><template:getname='footer'/></td></tr>
</table>
...

The inventory page uses the template listed above and specifies content for the edit panel:
<%@tagliburi='template.tld'prefix='template'%>
<%@tagliburi='security.tld'prefix='security'%>
<template:inserttemplate='/template.jsp'>
...
<template:putname='editPanel'
content='/editPanelContent.jsp'/>
...
</template:insert>

In contrast, the login page does not specify content for the edit panel:
<%@tagliburi='template.tld'prefix='template'%>
<template:inserttemplate='/template.jsp'>
<template:putname='title'content='Login'direct='true'/>
<template:putname='header'content='/header.jsp'/>
<template:putname='maincontent'
content='/login.jsp'/>
<template:putname='footer'content='/footer.jsp'/>
</template:insert>

Because the login page does not specify content for the edit panel, it's not included.

Role-based content
Web applications often discriminate content based on a user's role. For example, the same JSP template, which in

Figure 3.a. Inventory page for curators


Click on thumbnail to view full image (27 KB)

Figure 3.b. Inventory page for other users


Click on thumbnail to view full image (21 KB)

The template used in Figures 3.a and 3.b uses template:get's roleattribute:
<%@tagliburi='template.tld'prefix='template'%>
...
<table>
...
<td><template:getname='editPanel'role='curator'/></td></tr>
...
</table>
...

The get tag includes content only if the user's role matches the role attribute. Let's look at how the tag handler f
publicclassGetTagextendsTagSupport{
privateStringname=null,role=null;
...
publicvoidsetRole(Stringrole){this.role=role;}
...
publicintdoStartTag()throwsJspException{
...
if(param!=null){
if(roleIsValid()){
//includeorprintcontent...
}
}
...
}
privatebooleanroleIsValid(){

returnrole==null||//validifroleisn'tset
((javax.servlet.http.HttpServletRequest)
pageContext.getRequest()).isUserInRole(role);
}
}

Implementing templates
The templates discussed in this article are implemented with three custom tags:

template:insert

template:put

template:get

The insert tag includes a template, but before it does, put tags store information -- a name, URI, and Boolean v
template:put

stores beans in request scope but not directly because if two templates use the same content name

To ensure that each template has access only to its own information, template:insert maintains a stack of hash

Figure 4. Storing template parameters in request scope


Click on thumbnail to view full image (24 KB)

Each template in Figure 4 accesses the correct footer; footer.html for template_1.jsp and footer_2.html for tem
Template tag implementations
The remainder of this article examines the implementation of the three template tags: insert, put, and get. We

Figure 5. Sequence diagrams for the put and insert tags


Click on thumbnail to view full image (24 KB)

If a template stack does not already exist, the insert start tag creates one and places it in request scope. A hashta
Each put start tag creates a PageParameter bean, stored in the hashtable created by the enclosing insert tag.

The insert end tag includes the template. The template uses get tags to access the beans created by put tags. Afte
Figure 6 shows the sequence diagram for template:get.

Figure 6. Sequence diagrams for the get tag


Click on thumbnail to view full image (11 KB)

Template tag listings


Tag handler implementations for the template tags prove straightforward. Example 3.a lists the InsertTag class

Example 3.a. InsertTag.java


packagetags.templates;
importjava.util.Hashtable;
importjava.util.Stack;
importjavax.servlet.jsp.JspException;
importjavax.servlet.jsp.PageContext;
importjavax.servlet.jsp.tagext.TagSupport;
publicclassInsertTagextendsTagSupport{
privateStringtemplate;
privateStackstack;

//settermethodfortemplateattribute
publicvoidsetTemplate(Stringtemplate){
this.template=template;
}
publicintdoStartTag()throwsJspException{
stack=getStack();//obtainareferencetothetemplatestack
stack.push(newHashtable());//pushnewhashtableontostack
returnEVAL_BODY_INCLUDE;//passtagbodythroughunchanged
}
publicintdoEndTag()throwsJspException{
try{
pageContext.include(template);//includetemplate
}
catch(Exceptionex){//IOExceptionorServletException
thrownewJspException(ex.getMessage());//recastexception
}
stack.pop();//pophashtableoffstack
returnEVAL_PAGE;//evaluatetherestofthepageafterthetag
}
//taghandlersshouldalwaysimplementrelease()because
//handlerscanbereusedbytheJSPcontainer
publicvoidrelease(){
template=null;
stack=null;
}
publicStackgetStack(){
//trytogetstackfromrequestscope
Stacks=(Stack)pageContext.getAttribute(
"templatestack",
PageContext.REQUEST_SCOPE);
//ifthestack'snotpresent,createanewoneand
//putitintorequestscope
if(s==null){
s=newStack();
pageContext.setAttribute("templatestack",s,
PageContext.REQUEST_SCOPE);
}
returns;
}
}

Example 3.b lists the PutTag class, the tag handler for template:put:
Example 3.b. PutTag.java
packagetags.templates;
importjava.util.Hashtable;
importjava.util.Stack;
importjavax.servlet.jsp.JspException;
importjavax.servlet.jsp.tagext.TagSupport;

importbeans.templates.PageParameter;
publicclassPutTagextendsTagSupport{
privateStringname,content,direct="false";
//settermethodsforPuttagattributes
publicvoidsetName(Strings){name=s;}
publicvoidsetContent(Strings){content=s;}
publicvoidsetDirect(Strings){direct=s;}
publicintdoStartTag()throwsJspException{
//obtainareferencetoenclosinginserttag
InsertTagparent=(InsertTag)getAncestor(
"tags.templates.InsertTag");
//puttagsmustbeenclosedinaninserttag
if(parent==null)
thrownewJspException("PutTag.doStartTag():"+
"NoInsertTagancestor");
//gettemplatestackfrominserttag
Stacktemplate_stack=parent.getStack();
//templatestackshouldneverbenull
if(template_stack==null)
thrownewJspException("PutTag:notemplatestack");
//peekathashtableonthestack
Hashtableparams=(Hashtable)template_stack.peek();
//hashtableshouldneverbenulleither
if(params==null)
thrownewJspException("PutTag:nohashtable");
//putanewPageParameterinthehashtable
params.put(name,newPageParameter(content,direct));
returnSKIP_BODY;//notinterestedintagbody,ifpresent
}
//taghandlersshouldalwaysimplementrelease()because
//handlerscanbereusedbytheJSPcontainer
publicvoidrelease(){
name=content=direct=null;
}
//conveniencemethodforfindingancestornameswith
//aspecificclassname
privateTagSupportgetAncestor(StringclassName)
throwsJspException{
Classklass=null;//can'tnamevariable"class"
try{
klass=Class.forName(className);
}
catch(ClassNotFoundExceptionex){

thrownewJspException(ex.getMessage());
}
return(TagSupport)findAncestorWithClass(this,klass);
}
}
PutTag.doStartTag

creates a PageParameter bean -- listed in Example 3.c. -- subsequently stored in request sc

Example 3.c. PageParameter.java


packagebeans.templates;
publicclassPageParameter{
privateStringcontent,direct;
publicvoidsetContent(Strings){content=s;}
publicvoidsetDirect(Strings){direct=s;}
publicStringgetContent(){returncontent;}
publicbooleanisDirect(){returnBoolean.valueOf(direct).booleanValue();}
publicPageParameter(Stringcontent,Stringdirect){
this.content=content;
this.direct=direct;
}
}
PageParameterserves

as a simple placeholder for the content and direct attributes set in the template:put

Example 3.d. GetTag.java


packagetags.templates;
importjava.util.Hashtable;
importjava.util.Stack;
importjavax.servlet.jsp.JspException;
importjavax.servlet.jsp.PageContext;
importjavax.servlet.jsp.tagext.TagSupport;
importbeans.templates.PageParameter;
publicclassGetTagextendsTagSupport{
privateStringname;
//settermethodfornameattribute
publicvoidsetName(Stringname){
this.name=name;
}
publicintdoStartTag()throwsJspException{
//obtainreferencetotemplatestack

Stackstack=(Stack)pageContext.getAttribute(
"templatestack",PageContext.REQUEST_SCOPE);
//stackshouldnotbenull
if(stack==null)
thrownewJspException("GetTag.doStartTag():"+
"NOSTACK");
//peekathashtable
Hashtableparams=(Hashtable)stack.peek();
//hashtableshouldnotbenull
if(params==null)
thrownewJspException("GetTag.doStartTag():"+
"NOHASHTABLE");
//getpageparameterfromhashtable
PageParameterparam=(PageParameter)params.get(name);
if(param!=null){
Stringcontent=param.getContent();
if(param.isDirect()){
//printcontentifdirectattributeistrue
try{
pageContext.getOut().print(content);
}
catch(java.io.IOExceptionex){
thrownewJspException(ex.getMessage());
}
}
else{
//includecontentifdirectattributeisfalse
try{
pageContext.getOut().flush();
pageContext.include(content);
}
catch(Exceptionex){
thrownewJspException(ex.getMessage());
}
}
}
returnSKIP_BODY;//notinterestedintagbody,ifpresent
}
//taghandlersshouldalwaysimplementrelease()because
//handlerscanbereusedbytheJSPcontainer
publicvoidrelease(){
name=null;
}
}
GetTag.doStartTag

retrieves the page parameter bean from request scope and obtains the content and direct

Conclusion
Templates are a simple but useful concept that should be in every JSP developer's repertoire. Templates encapsul

Templates are not a standard JSP feature, but you can easily implement them with custom tags, as discussed in th
Resources

To download this article's complete source code as a JAR file, go to:


GettingStartedFiles.zip

Core Servlets and JSP by Marty Hall (Prentice-Hall May 2000) provides an excellent introduction to serv
Amazon.com - Core Servlets and JavaServer Pages (JSP)

Designing Enterprise Applications with the Java 2 Platform, Enterprise Edition by Nicolas Kassem (Add
Amazon.com - Designing Enterprise Applications with the Java 2 Platform, Enterprise Edition

About the Author


David Geary, the author of the Graphic Java series from Sun Microsystems Press, is currently working on JSP: A
Microsystems to work full-time as an author and occasional speaker and consultant. David has been a columnist

You might also like