手机
当前位置:查字典教程网 >编程开发 >JSP教程 >JSP模板应用指南(下)
JSP模板应用指南(下)
摘要:执行模板这里所讨论的模板将在三种定制标签下执行:Template:insertTemplate:putTemplate:getinsert标...

执行模板

这里所讨论的模板将在三种定制标签下执行:

Template: insert

Template: put

Template: get

insert 标签中包含一个模板,但是在包含之前,put 标签存储有一些信息——name, URI和Boolean 值(用来指定将内容是包含还是直接显示)——关于模板所包含的内容。在template:get中包含(或显示)了指定的内容,随后将访问这些信息。

template:put 把Bean 存储在请求区域(但并不直接存储),因为如果两个模板使用了相同的内容名,一个嵌套模板就将覆盖封装模板中的内容。

为了保证每一个模板能够只存取它自己的信息,template:insert 保留了一个hashtable堆栈。每一个insert 开始标签建立一个 hashtable并把它放入堆栈。封装的put 标签建立bean并把它们保存到最近建立的hashtable中。随后,在被包含模板中的 get 标签访问hashtable中的bean。图 4 显示了堆栈是如何被保留的。

图 4. 在请求区域存储模板参数 点击放大(24 KB)

在图 4中每一个模板访问正确的页脚、footer.html 和footer_2.html。如果 bean被直接存储在请求区域,图 4中的step 5将覆盖在step 2中指定的footer bean。

模板标签执行

接下来我们将分析三个模板标签的执行: insert, put和get。我们先从图 5开始。这个图表说明了当一个模板被使用时,insert和put标签事件的执行顺序。

图 5. put和insert 标签执行顺序 点击放大(24 KB)

如果一个模板堆栈已经不存在,insert 开始标签就会建立一个并把它放置到请求区域。随后一个hashtable也被建立并放到堆栈中。

每一个 put 开始标签建立一个PageParameter bean,并存储在由封装的insert标签建立的hashtable中。

插入 end 标签包含了这个模板。这个模板使用get标签来访问由put标签建立的bean。在模板被处理以后,由insert 开始标签建立的hashtable就从堆栈中清除。

图 6显示template:get的顺序图表。

图 6. get标签的顺序图表 点击放大(11 KB)

模板标签列表

标签handler很简单。在例 3.a中列出了Insert标签类——标签handler。

例 3.a. InsertTag.java

packagetags.templates;

import java.util.Hashtable;

import java.util.Stack;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.PageContext;

import javax.servlet.jsp.tagext.TagSupport;

public class InserttagextendstagSupport {

private Stringtemplate;

private Stack stack;

// setter method fortemplate 属性

public void setTemplate(Stringtemplate) {

this.template =template;

}

public int doStartTag() throws JspException {

stack = getStack(); // obtain a reference to thetemplate stack

stack.push(new Hashtable()); // push new hashtable onto stack

return EVAL_BODY_INCLUDE; // pass tagbody through unchanged

}

public int doEndTag() throws JspException {

try {

pageContext.include(template); // includetemplate

}

catch(Exception ex) { // IOException or ServletException

throw new JspException(ex.getMessage()); // recast exception

}

stack.pop(); // pop hashtable off stack

return EVAL_PAGE; // evaluate the rest of the page after the tag

}

// taghandlers should always implement release() because

// handlers can be reused by the JSP container

public void release() {

template = null;

stack = null;

}

public Stack getStack() {

// try to get stack from request scope

Stack s = (Stack)pageContext.get属性(

"template-stack",

PageContext.REQUEST_SCOPE);

// if the stack's not present, create a new one和

// put it into request scope

if(s == null) {

s = new Stack();

pageContext.set属性("template-stack", s,

PageContext.REQUEST_SCOPE);

}

return s;

}

}

例 3.b 列出了 Put标签类和标签handler:

例 3.b. PutTag.java

packagetags.templates;

import java.util.Hashtable;

import java.util.Stack;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.tagext.TagSupport;

import beans.templates.PageParameter;

public class PuttagextendstagSupport {

private String name, content, direct="false";

// setter methods for Put tag attributes

public void setName(String s) { name = s; }

public void setContent(String s) {content = s; }

public void setDirect(String s) { direct = s; }

public int doStartTag() throws JspException {

// obtain a reference to enclosing insert tag

Inserttagparent = (InsertTag)getAncestor(

"tags.templates.InsertTag");

// puttags must be enclosed in an insert tag

if(parent == null)

throw new JspException("PutTag.doStartTag(): " +

"No Inserttagancestor");

// gettemplate stack from insert tag

Stacktemplate_stack = parent.getStack();

//template stack should never be null

if(template_stack == null)

throw new JspException("PutTag: notemplate stack");

// peek at hashtable on the stack

Hashtable params = (Hashtable)template_stack.peek();

// hashtable should never be null either

if(params == null)

throw new JspException("PutTag: no hashtable");

// put a new PageParameter in the hashtable

params.put(name, new PageParameter(content, direct));

return SKIP_BODY; // not interested in tagbody, if present

}

// taghandlers should always implement release() because

// handlers can be reused by the JSP container

public void release() {

name = content = direct = null;

}

// convenience method for finding ancestor names with

// a specific class name

privatetagSupport getAncestor(String className)

throws JspException {

Class klass = null; // can't name variable "class"

try {

klass = Class.forName(className);

}

catch(ClassNotFoundException ex) {

throw new JspException(ex.getMessage());

}

return (TagSupport)findAncestorWithClass(this, klass);

}

}

PutTag.doStarttag建立了一个 PageParameter bean – 在例 3.c中列出——然后存储到请求区域。

例 3.c. PageParameter.java

package beans.templates;

public class PageParameter {

private String content, direct;

public void setContent(String s) {content = s; }

public void setDirect(String s) { direct = s; }

public String getContent() { return content;}

public boolean isDirect() { return Boolean.valueOf(direct).booleanValue(); }

public PageParameter(String content, String direct) {

this.content = content;

this.direct = direct;

}

}

PageParameter将作为简单的占位符使用。我们来看一看例 3.d中的Gettag类和tag handler:

例 3.d. GetTag.java

packagetags.templates;

import java.util.Hashtable;

import java.util.Stack;

import javax.servlet.jsp.JspException;

import javax.servlet.jsp.PageContext;

import javax.servlet.jsp.tagext.TagSupport;

import beans.templates.PageParameter;

public class GettagextendstagSupport {

private String name;

// setter method for name attribute

public void setName(String name) {

this.name = name;

}

public int doStartTag() throws JspException {

// obtain reference totemplate stack

Stack stack = (Stack)pageContext.get attribute (

"template-stack", PageContext.REQUEST_SCOPE);

// stack should not be null

if(stack == null)

throw new JspException("GetTag.doStartTag(): " +

"NO STACK");

// peek at hashtable

Hashtable params = (Hashtable)stack.peek();

// hashtable should not be null

if(params == null)

throw new JspException("GetTag.doStartTag(): " +

"NO HASHTABLE");

// get page parameter from hashtable

PageParameter param = (PageParameter)params.get(name);

if(param != null) {

String content = param.getContent();

if(param.isDirect()) {

// print content if direct attribute is true

try {

pageContext.getOut().print(content);

}

catch(java.io.IOException ex) {

throw new JspException(ex.getMessage());

}

}

else {

// include content if direct attribute is false

try {

pageContext.getOut().flush();

pageContext.include(content);

}

catch(Exception ex) {

throw new JspException(ex.getMessage());

}

}

}

return SKIP_BODY; // not interested in tagbody, if present

}

// taghandlers should always implement release() because

// handlers can be reused by the JSP container

public void release() {

name = null;

}

}

GetTag.doStartTag从请求区域返回了页面参数bean并从bean中获得了content和direct 属性。然后,内容可以根据direct属性值选择是被包含还是显示。

结论

模板是一种简单而有非常有用的概念。模板的封装布局能够对布局改变的影响达到最小化。而且模板能够根据用户的不同来区分不同的内容,它还能够嵌套到其他的模板和JSP页面中。

<全文完>

【JSP模板应用指南(下)】相关文章:

实例讲解JSP Model2体系结构(上)

JSP上传文件到指定位置

JSP语法Page指令

JSP教程(五)-JSP Actions的使用下

JSP开发导引

JSP和JAVA的含义

JDBCTM 指南:入门

JSP技术生成动态web页面

jsp JFreeChart使用心得与例子

JSP数据库操作例程(Use Bean)

精品推荐
分类导航