什么样的生活也要珍惜。如果现在你正幸福着你的幸福,那好,尽情享受它,不要浪费;如果现在你正痛苦着你的痛苦,那也不要紧,痛苦过后或许就是新生;如果现在你的生活平平淡淡,那么,更应好好珍惜它,因为,这才是生活的真谛。
执行模板 这里所讨论的模板将在三种定制标签下执行: 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模板应用指南(下)请关注haodaima.com其它相关文章!