侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

JSP模板应用指南(下)

Java  /  管理员 发布于 7年前   178

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

  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 C 在例 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模板应用指南(上)
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在java中实现的脱敏工具类代码示例分享(0个评论)
    • zookeeper安装流程步骤(0个评论)
    • 在java中你背的“八股文”可能已经过时了(2个评论)
    • 在php8.0+版本中使用属性来增加值代码示例(3个评论)
    • java 正则表达式基础,实例学习资料收集大全 原创(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-11
    • 2018-03
    • 2020-03
    • 2023-05
    • 2023-11
    • 2024-01
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客