• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    JSP模板应用指南(下)
    执行模板
      这里所讨论的模板将在三种定制标签下执行:

      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简明教程:令人兴奋的脚本编程
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    JSP模板应用指南(下) JSP,模板,应用,指南,下,JSP,