当前位置: 首页 > 图文教程 > 网络编程 > JSP > JSP模板应用指南(下)

JSP
jsp计数器制作
用jsp编写文件上载
基于JSP的动态网站开发技术
JSP由浅入深(3)—— 通过表达式增加动态内容
JSP由浅入深(5)—— Scriptlets和HTML的混合
JSP由浅入深(1)—— 熟悉JSP服务器
JSP由浅入深(12)—— 表单编辑
JSP由浅入深(11)—— 标记库
JSP由浅入深(10)—— Beans and Forms处理
JSP由浅入深(9)—— JSP Sessions
JSP由浅入深(8)—— JSP Tags
JSP由浅入深(6)—— JSP声明
JSP由浅入深(4)—— Scriptlets
JSP由浅入深(2)—— 第一个JSP
JSP由浅入深(7)—— JSP Directives
JSP中的字符替换函数 str_replace() 实现!
把一张图片变形扭曲成各种不同的长宽
用JSP编写通用信息发布程序
Java Servlet及Cookie的使用
Apache+Servlet+Jsp环境设置(上)

JSP模板应用指南(下)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 50 ::
收藏到网摘: n/a

执行模板
  这里所讨论的模板将在三种定制标签下执行:
  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页面中。
  <全文完>