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

JSP
我认为JSP有问题(上)
我认为JSP有问题(下)
jsp“抓”网页代码的程序
关于在bean里面打印html的利弊看法
bean里面如何打印到html页面
jdbc3中的RowSet 接口规范
Apusic Application Server1.0中jsp源代码泄漏漏洞
Unify的eWave ServletExec拒绝服务漏洞
通过提交超长的GET请求导致IBM HTTP Server远程溢出
在HTTP请求中添加特殊字符导致暴露JSP源代码文件
Resin 1.2 重要源代码暴露漏洞
多中WEB服务器的通用JSp源代码暴露漏洞
Tomcat 暴露JSP文件内容
IBM WebSphere Application Server 暴露JSP文件内容
JRun 2.3.x 范例文件暴露站点安全信息
BEA WebLogic 暴露源代码漏洞
IBM WebSphere Application Server 3.0.2 存在暴露源代码漏洞
Tomcat 3.1 存在暴露网站路径问题
Sun Java Web Server 能让攻击者远程执行任意命令
Netscape 修复 JAVA 安全漏洞

JSP模板应用指南(下)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-13   浏览: 70 ::
收藏到网摘: 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页面中。
  <全文完>