精华内容
下载资源
问答
  • 主要介绍了jsp通过自定义标签库实现数据列表显示的方法,较为详细的分析了jsp自定义标签的定义、功能实现与使用技巧,并附带了完整的实例代码供读者下载参考,需要的朋友可以参考下
  • jsp自定义标签库实现数据列表显示,包括代码,文档,希望对大家有帮助.
  • 文章标题: 使用jsp自定义标签库实现数据列表显示模拟cms4j中的标签库效果   作者: javaboy2012 Email:yanek@163.com qq: 1046011462     cms4j中调用方式:     下面例子实现类似效果:   运行...


    文章标题: 使用jsp自定义标签库实现数据列表显示模拟cms4j中的标签库效果

     

    作者: javaboy2012
    Email:yanek@163.com
    qq:    1046011462

     

     

    cms4j中调用方式:

     

     

    下面例子实现类似效果:

     

    运行效果:

     

    具体如下:


    jsp调用代码:


    <%@ page language="java" import="java.util.*,com.yanek.cms.vo.*" pageEncoding="UTF-8"%>
    <%@ taglib uri="/tags/my-cms" prefix="myTag" %>
    <body>
    <myTag:articleListTag  cateid="1">
     
        <%=article_info.getId() %>------
                <%=article_info.getTitle() %> <br>
               
                ${article_info.id }---- ${article_info.title }<br>

    </myTag:articleListTag>
    <hr>

    <myTag:articleListTag  cateid="2">
     
        <%=article_info.getId() %>------
                <%=article_info.getTitle() %> <br>
               
                ${article_info.id }---- ${article_info.title }<br>

    </myTag:articleListTag>
     </body>
    </html>

     

    标签库定义


    <!-- articleListTag start -->

        <tag>

           <name>articleListTag</name>

           <tag-class>com.yanek.cms.tag.ArticleTag</tag-class>

       
           <body-content>jsp</body-content>
       
          <variable>
            <name-given>article_info</name-given>
            <!--<name-from-attribute>name</name-from-attribute>-->
            <variable-class>com.yanek.cms.tag.Article</variable-class>
            <declare>true</declare>
            <scope>NESTED</scope>
          </variable>

           <attribute>
            <name>cateid</name>
            <required>true</required>
           </attribute>
     
    </tag>

    <!-- articleListTag end -->

     


    标签库类

    package com.yanek.cms.tag;

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.BodyTagSupport;

    public class ArticleTag extends BodyTagSupport {

     private Iterator it;// 要迭代的对象
     private int cateid; // 文章类别id
     
     public final static String name = "article_info";

     @Override
     public int doEndTag() throws JspException {
      try {
       if (bodyContent != null) {
        bodyContent.writeOut(bodyContent.getEnclosingWriter());
       }
      } catch (IOException e) {
       e.printStackTrace();

      }
      return EVAL_PAGE;
     }

     @Override
     public int doStartTag() throws JspException {

      //这里根据文章分类,构造不同的列表数据,实际可以根据数据库获取
      List<Article> articles = new ArrayList<Article>();
      if (cateid == 1) {
       articles.add(new Article(1, "asp"));

       articles.add(new Article(2, "jsp"));
      } else {
       articles.add(new Article(3, "php"));

       articles.add(new Article(4, "java"));
      }
      it = articles.iterator();

      if (it == null) {
       return SKIP_BODY;

      } else {
       return continueNext();
      }
     }

     private int continueNext() {
      if (it.hasNext()) {
       pageContext.setAttribute(name, it.next(), pageContext.PAGE_SCOPE);
       return EVAL_BODY_TAG;
      } else {

       return SKIP_BODY;
      }
     }

     @Override
     public int doAfterBody() {
      return continueNext();
     }


     public int getCateid() {
      return cateid;
     }

     public void setCateid(int cateid) {
      this.cateid = cateid;
     }

    }

     

    标签库引用实体类

    package com.yanek.cms.tag;

    public class Article {
     
     private int id;
     private String title;
     public int getId() {
      return id;
     }
     public void setId(int id) {
      this.id = id;
     }
     public String getTitle() {
      return title;
     }
     public void setTitle(String title) {
      this.title = title;
     }
     public Article(int id, String title) {
      super();
      this.id = id;
      this.title = title;
     }
     
     public Article() {
      super();
      this.id = id;
      this.title = title;
     }
     
     
     

    }

     

    几点说明:标签调用是显示list中对象时采用的脚本变量名字article_info 是在标签库定义文件和标签库类中定义的,如下

        <variable>
            <name-given>article_info</name-given>
            <!--<name-from-attribute>name</name-from-attribute>-->
            <variable-class>com.yanek.cms.tag.Article</variable-class>
            <declare>true</declare>
            <scope>NESTED</scope>
          </variable>

    标签库类中
    public final static String name = "article_info";
    pageContext.setAttribute(name, it.next(), pageContext.PAGE_SCOPE);

     

    显示列表中对象的方式有2种方式:

    调用类的方法:  在eclipse中可以方法提示。

            <%=article_info.getId() %>---- <%=article_info.getTitle() %>

    jstl显示:

           ${article_info.id }---- ${article_info.title }

     

     

    展开全文
  • 本文实例讲述了ThinkPHP分组下自定义标签库实现方法。分享给大家供大家参考。具体如下: 自定义标签库应该位于ThinkPHP\\Extend\\Driver\\TagLib目录下 1 新建标签类库文件名为TagLibBlog.class.php。 2 编辑刚才...
  • java自定义标签库的开发

    千次阅读 2016-08-05 11:47:52
    java自定义标签库的开发 第14章 自定义标签库的开发  14.1 自定义标签介绍 14.2 HelloWorld标签的开发 14.3 开发带Body的标签库 14.4 多个标签的嵌套 14.5 开发迭代的标签库 14.6 SimpleTag...
    java自定义标签库的开发

    第14章 自定义标签库的开发 

    14.1 自定义标签介绍
    14.2 HelloWorld标签的开发
    14.3 开发带Body的标签库
    14.4 
    多个标签的嵌套
    14.5 开发迭代的标签库
    14.6 SimpleTag开发

    14.1 标签语言的介绍 本章开头 下一节

    JSP标签库(也称自定义库)可看成是一套产生基于XML脚本的方法,它经由JavaBeans来支持。在概念上说,标签库是非常简单和可以重用的代码构造。

     自定义标签有着丰富的特点,它们可以:

    1.可以通过调用页面传递的属性进行自定义;
    2.可以访问对于JSP页面可能的所有对象;
    3.可以修改由调用页面产生的响应。
    4.可以相互间通信。你可以创建并初始化一个JavaBean组件,创建一个变量引用标签中的bean,接着在其它的标签中引用该bean.
    5.可以在一个标签中嵌套另一个,可以在JSP页面中进行复杂的交互。

     下面的代码声明在网页中使用新的标签,这个标签以hello为前缀,访问的路径为/demotag。

    <%@ taglib uri="/demotag" prefix="hello" %>

      自定义标签为在JSP项目中创建易于重用的代码打开了一扇大门。你所需要的只是标签库和它的文档说明。

      通过实现接口或者继承现有的类,我们就可以开发自定义的标签。
    常用的接口有:

    TagSupport类

      该类是IterationTag的缺省实现。除了实现原有方法外,本身还增加了一些有用的其他方法和成员变量。下表列出其中重要的几个:

    名称 描述 
    重写的方法和他们的返回值  
    void doStartTag() 继承自Tag。返回值SKIP_BODY。 
    void doAfterBody() 继承自IterationTag。返回值SKIP_BODY。 
    void doEndTag() 继承自Tag。返回值EVAL_PAGE。 
    处理嵌套标签的有用的方法  
    void setParent(Tag) 接受和维护一个父标签的引用。 
    Tag getParent()返回父标签的引用。 
    Tag findAncestorWithClass(Tag,Class) 静态方法。寻找最近的指定类的标签。 
    标签属性操作  
    void setValue(String,Object) 设置属性。属性名是字符串,值可以是任何对象。 
    Object getValue(String) 返回给定属性名的属性的值。 
    Enumeration getValues() 返回一个所有值的枚举。 
    void removeValue(String) 删除给定的属性。 
    受保护的实例变量  
    PageContext pageContext 一个保存着PageContext对象的变量。 
     
    BodyTagSupport类

     该类同时继承了TagSupport类,并实现BodyTag接口。除了前表所示方法,该类还提供了一些其它方法便于使用。
     

    名称 描述 
    重写的方法和他们的返回值  
    void doStartTag() 继承自Tag。返回值EVAL_BODY_BUFFERED。 
    void doAfterBody() 继承自IterationTag。返回值SKIP_BODY。 
    void doEndTag() 继承自Tag。返回值EVAL_PAGE。 
    用以处理缓冲的方法  
    void setBodyContent(BodyContent) 接受和维护一个BodyContent对象(缓冲对象)的引用。 
    BodyContent getBodyContent() 返回BodyContent对象的引用。 
    JspWriter getPreviousOut() 返回JspWriter对象,BodyContent就是对他的简单包裹。 

    实现Tag接口

      所有的标签处理器都需要间接或直接的实现这个接口。

      下面列出Tag接口定义的方法和常量:

    方法名 描述 
    int doStartTag()  当碰到标签起始标记时执行。(<XXX:XXX>) 
    int doEndTag() 当碰到标签结束标记时执行。(</XXX:XXX>) 
    Tag getParent() 获得一个父标签对象 
    void release() 从内存中释放该标签对象 
    void setPageContext(PageContext) 设置当前页上下文(page context) 
    void setParent(Tag) 对父标签对象进行设置 
     
    常量 描述 
    EVAL_BODY_INCLUDE doStartTag()的返回值。指出jsp引擎计算标记体并输出
    SKIP_BODY doStartTag()的返回值。指出jsp引擎跳过标记体且不输出 
    EVAL_PAGE doEndTag()的返回值。指出jsp引擎计算页面剩余部分并输出 
    SKIP_PAGE doEndTag()的返回值。指出jsp引擎跳过页面剩余部分且不输出 

    setPageContext()方法
    setPageContext()方法是一个定制标签声明周期内第一个要被调用的方法。完整写法是:
    public void setPageContext(PageContext);
    jsp引擎会将jsp页转换时隐含创建的pageContext对象,作为参数,调用setPageContext方法。
    通常的做法会将这个参数保存为本标记处理器的参数。

    setParent()和getParent()方法
    当标签嵌套使用时,外层的标签被成为父标签,内部的被称为子标签。完整的写法是:
    public void setParent(Tag);
    public Tag getParent();
    其中setParent方法对父标签对象进行设置。而getParent方法用以获得父标签对象。

    setter方法
    当定制标签中包含属性时,在标签处理器中有和javaBean相同的设置机制。即每一个属性XXX,都有对应的setXXX()方法。
    这些方法的调用是在setPageContext()和setParent()之后,doStartTag()之前。(就是说所有的属性-即实例变量-必须完全赋值,因为随后的方法可能会调用到它们)

    doStartTag()方法
    该方法标志着真正的标签处理开始。当前三阶段的方法执行完后,jsp引擎就会调用doStartTag()方法了。完整写法是:
    public int doStartTag() throws JspException;
    该方法给了标签处理器一个初始化计算和校验属性值合法性的机会。如果初始化失败或属性值不合法,则抛出JspException异常,或其子类,如JspTagException。
    初始化计算过后,该方法将决定是否继续对标签体进行计算。作为结果,返回一个整数常量(EVAL_BODY_INCLUDE或SKIP_BODY),用以指示是否跳过标签体的执行。除此之外不返回任何其它值。

    doEndTag()方法
    执行完doStartTag()方法后,就该执行doEndTag()了。完整写法是:
    public int doEndTag() throws JspException;
    该方法标志着真正的标签处理结束。同样该方法将决定是否继续执行jsp文件中该标签之后的内容。它也会返回一个整数常量(EVAL_PAGE或SKIP_PAGE),用以指示页面后续内容是否跳过。注意此处的范围是页,并不是转换单位。所以计算不计算全都是针对该页而言。

    release()方法
    最后,jsp引擎将调用release方法,当标签处理结束,标签处理器对象不再使用时。完整写法是:
    public void release();
    注意。一个页面内同时有多个相同标签时,jsp引擎会只会为该标签创建一个对象。只有等该页内相同标签全部处理完了。jsp引擎才会调用release()方法,将该标签对象从内存清理掉。

      自定义标签的开发包括两个部分的开发:
    (1)开发标签的处理程序(java类)
    (2)标签描述文件(.tld文件)

      自定义标签的种类有许多,可以根据实际项目的需要进行编写。但为了不重复的开发,jsp标准推出JSTL(标准标签库)。

      在JSP应用程序中添加自定义标签的能力可以使工作重点放到以文档为中心的开发方式上。可以使 Java 代码不出现在 JSP 页中,从而使这些页面更容易维护。

      在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象(Java类)。在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对,这样页面编译时才能处理你的自定义标签。通过在 Web 部署描述符(web.xml)中声明库导入它,然后用指令taglib将它导入 JSP 页。

      如果JSP容器在编译JSP文件时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor)(TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一样。

      对正文进行操作 —— 即对在开始和结束标签之间的内容进行操作的 —— 标签必须实现 BodyTag 接口。我们将称这些标签为正文标签。我们将不对其正文操作的标签称为简单标签。简单标签可以实现Tag接口,尽管不要求它们这样做。要记住不对其正文操作的标签仍然有正文,只不过,它的标签处理程序不能读取这个正文。
    要构建简单标签,我们需要完成以下步骤:

    1. 创建实现了Tag接口(准确地说是 javax.servlet.jsp.tagext.Tag)的标签处理程序类。
    2. 创建一个 TLD 文件。 
    3. 在标签处理程序 Java 类中创建属性。 
    4. 在 TLD 文件中定义与标签处理程序 Java 类中定义的属性对应的属性。 
    5. 在 TLD 文件中声明 scriptlet 变量。 
    6. 实现 doStartTag() 方法。在标签处理程序类中,根据属性将值设置到 scriptlet 变量中。

      在jsp1.2时代已经有标记库了, 并且功能强大,但标记库的编程和调用都比较复杂,导致真正使用到WEB开发中的还是不多。JSP2.0推出的简单标记库扩展解决了以上的问题。简单标记库相对JSP1.2中的标记库来说,优点在于对后台程序员来说,结构更简单,实现接口更少,可以轻松实现后台程序。

      JSP 2.0中加入了新的创建自制标记的API:javax.servlet.jsp.tagext.SimpleTag,该API定义了用来实现简单标记的接口。和JSP 1.2中的已有接口不同的是,SimpleTag接口不使用doStartTag()和doEndTag()方法,而提供了一个简单的doTag()方法。这个方法在调用该标记时只被使用一次。而需要在一个自制标记中实现的所有逻辑过程、循环和对标记体的评估等都在这个方法中实现。从这个方面来讲,SimpleTag可以和IterationTag达到同等的作用。但SimpleTag的方法和处理周期要简单得多。在SimpleTag中还有用来设置JSP内容的setJspBody()和getJspBody()方法。Web容器会使用setJspBody()方法定义一个代表JSP内容的JspFragment对象。实现SimpleTag标记的程序可以在doTag方法中根据需要多次调用getJspBody().invoke()方法以处理JSP内容。

    自定义标签的分类:
    (1)不带主体和属性的简单标签:如< mytag:helloworld/>
    (2)不带主体但有属性的标签:如<imytag:checkinput dbname = “<myBean.getDBName()>”/>
    (3)带标签体和属性的标签:在自定义标签的起始和结束标签之间的部分为标签体(Body)。Body的内容可以是JSP中的标准标签,也可以是HTML、脚本语言或其他的自定义标签。
    <mytag:checkinput dbname ="<myBean.getDBName()>">
      <mytag:log message="Table Name">
    <mytag:checkinput />
    (4使用脚本变量的标签:
    定义了id和type属性的标签可以被标签后面的Scriptlet使用。
    <mytag:connection id = "sqlDB" type ="DataSource" name ="SQL_Server">
    <%sqlDB.getConnection(); %>
     

    14.2 HelloWorld标签的开发 上一节 下一节 本章开头

      传统的标签必须实现javax.servlet.jsp.tagext.Tag接口,在Tag接口中,主要定义的是和标签生命周期相关的方法,比如:doStartTag(),doEndTag()等。在Tag中,可以通过PageContext对象来访问JSP页面的上下文。结合标签的生命周期标签的处理过程:

     1当容器创建一个新的标签实例后,通过setPageContext()来设置标签的页面上下文。

     2使用setParent方法设置这个标签的上一级标签,如果没有上一级嵌套,设置为null。

     3设置标签的属性,这个属性在标签库描述文件中定义,如果没有定义属性,就不用调用此类方法。

     4调用doStartTag方法,这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,当返回EVAL_BODY_INCLUDE时,就计算标签的Body,如果返回SKIP_BODY,就不计算标签的Body。

     5调用doEndTag方法,这个方法可以返回EVAL_PAGE或者SKIP_PAGE,当返回EVAL_PAGE时,容器将在标签结束时继续计算JSP页面其他的部分;如果返回SKIP_PAGE,容器将在标签结束时停止计算JSP页面其他的部分。

     6调用release方法释放标签程序占用的任何资源。

      开发标签时可以有两种选择,已从是实现原始的接口,另一种是从TagSupport类继承。

    14.2.1 实现Tag接口

      按照下面的步骤进行:

     1)开发标签实现类

     2)编写标签描述文件,tld为扩展名。

     3)在Web.xml中映射标签库的使用。

     4)在JSP网页中调用标签。

    14.2.1.1开发实现类

      教材例程14-1,HelloTag_Interface.java文件。

    package com.jspdev.ch14;

     

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.Hashtable;

    import java.io.Writer;

    import java.io.IOException;

    import java.util.Date;      

     

    /**

     *演示怎么实现Tag接口的方式来开发标签程序

     */

    public class HelloTag_Interface implements javax.servlet.jsp.tagext.Tag

    {

         private PageContext pageContext;

         private Tag parent;

         public HelloTag_Interface()

         { 

           super();

         }

        

        /**

          *设置标签的页面的上下文

          */

         public void setPageContext(final javax.servlet.jsp.PageContext pageContext)

         {

               this.pageContext=pageContext; 

         }

        

        /**

          *设置上一级标签

          */

         public void setParent(final javax.servlet.jsp.tagext.Tag parent)

         {  

              this.parent=parent;  

         }

        

         /**

          *开始标签时的操作

          */

         public int doStartTag() throws javax.servlet.jsp.JspTagException 

         {  

              return SKIP_BODY;  //返回SKIP_BODY,表示不计算标签体

         }

        

         /**

          *结束标签时的操作

          */

         public int doEndTag() throws javax.servlet.jsp.JspTagException 

         {

               try

               {  

                    pageContext.getOut().write("Hello World!你好,世界!");

               }                 

              catch(java.io.IOException e)

              {

                   throw new JspTagException("IO Error: " + e.getMessage());

              } 

              return EVAL_PAGE;

          }

        

         /**

          *release用于释放标签程序占用的资源,比如使用了数据库,那么应该关闭这个连接。

          */

         public void release() {}   

       

       

         public javax.servlet.jsp.tagext.Tag getParent()  

         {   

            return parent;

         }

    }

    14.2.1.2编写标签库描述

    教材例程14-2,mytag.tld文件。

    <?xml version="1.0" encoding="ISO-8859-1" ?>

     

    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"

        version="2.0">

        <description>A tag library exercising SimpleTag handlers.</description>

        <tlib-version>1.0</tlib-version>

     

      <short-name>examples</short-name>

      <uri>/demotag</uri>

      <description>

        A simple tab library for the examples

      </description>

     

     <tag>

        <description>Outputs Hello, World,从实现Tag接口起开发</description>

            <name>hello_int</name>

        <tag-class>com.jspdev.ch14.HelloTag_Interface</tag-class>

        <body-content>empty</body-content>

     </tag>

     

    </taglib>

    14.2.1.3 在Web.xml中映射标签库的使用。

    <web-app>

    ...

    <taglib>
    <taglib-uri>/demotag</taglib-uri>
    <taglib-location>/WEB-INF/tlds/mytag.tld</taglib-location>
    </taglib>

    ...
    </web-app>

    14.2.1.4 在JSP网页中调用标签

      教材例程14-4hellotag_interface.jsp文件。

    <%@ taglib uri="/demotag" prefix="hello" %>
    <%@ page contentType="text/html; charset=gb2312" language="java" %>
    <html>
    <head>
    <title>first cumstomed tag</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>

    <body>
    <p>以下的内容从Taglib中显示:</p>
    <p><i><hello:hello_int/></i></p>
    </body>
    </html>

      运行结果如下图所示。

    14.2.2 从TagSupport继承

      只需要覆盖TagSupport类的doStartTag和doEndTag两个方法即可,开发比较容易。

    教材例程14-5,HelloTag.java文件。

    package com.jspdev.ch14;

     

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.Hashtable;

    import java.io.Writer;

    import java.io.IOException;

    import java.util.Date;       

     

    /**

     *演示从TagSupport继承来开发标签

     */

    public class HelloTag extends TagSupport

    {

        /**

         *覆盖doStartTag方法

         */

        public int doStartTag() throws JspTagException {

        return EVAL_BODY_INCLUDE;

        }

       

        /**

         *覆盖doEndTag方法

         */

        public int doEndTag()throws JspTagException

        {

            String dateString =new Date().toString();

            try

            {

                pageContext.getOut().write("Hello World hellking.<br>现在的时间是:"+dateString);

               

            }

            catch(IOException ex)

            {

                throw new JspTagException("Fatal error:hello tag conld not write to JSP out");

            }

            return EVAL_PAGE;

        }

    }

    教材例程14-6,mytag.tld文件,同上例,加一段映射即可。

    ...

     

      <tag>

        <name>hello</name>

        <tag-class>com.jspdev.ch14.HelloTag</tag-class>

        <body-content>empty</body-content>

        <description>

        Simple hello world examples.

        Takes no attribute,and simply generates HTML

        </description>

      </tag>

     

    ...

    教材例程14-7,helloworld_tag.jsp文件。

    <%@ taglib uri="/demotag" prefix="hello" %>
    <%@ page contentType="text/html; charset=gb2312" language="java" %>
    <html>
    <head>
    <title>first cumstomed tag</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>

    <body>

    <p>以下的内容从Taglib中显示:</p>
    <p><i><hello:hello/></i></p>
    </body>
    </html>

    运行结果如下图所示。

    14.3 开发带Body的标签库 上一节 下一节 本章开头

      带有Body的Tag必须实现javax.servlet.jsp.tagext.BodyTag接口,BodyTag接口中定义了一些处理标签体的方法。

      通过实现BodyTag接口,就可以方便的操作标签体,比如可以让标签体迭代多次等。BodyTag的处理过程:

     1)当容器创建一个新的标签实例后,通过setPageContext来设置标签的页面上下文。 
     2)使用setParent方法设置这个标签的上一级标签。 
     3)设置标签的属性。 
     4)调用doStartTag方法,这个方法可以返回EVAL_BODY_INCLUDE和SKIP_BODY,当返回EVAL_BODY_INCLUDE时,就计算标签的Body,如果返回SKIP_BODY,就不计算标签的Body。 
     5)调用setBodyContent设置当前的BodyContent。 
     6)调用doInitBody,如果在计算BodyContent时需要进行一些初始化,就在这个方法中进行。 
     7)每次计算完BodyTag后调用doAfterBody,如果返回EVAL_BODY_TAG,表示继续计算一次BodyTag,直接返回SKIP_BODY才继续执行doEndTag方法。 
     8)调用doEndTag方法,这个方法可以返回EVAL_PAGE或者SKIP_PAGE,当返回EVAL_PAGE时,容器将在标签结束时继续计算JSP页面其他的部分;如果返回SKIP_PAGE,容器将在标签结束时停止计算JSP页面其他的部分。 
     9)调用release()方法释放标签程序占用的任何资源。

    教材例程14-8,BodyTagExample.java文件。

    package com.jspdev.ch14;

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.Hashtable;

    import java.io.Writer;

    import java.io.IOException;

     

    public class BodyTagExample extends BodyTagSupport

    {

           int counts;//counts为迭代的次数。

           public BodyTagExample()

           {

                  super();

           }

          

           /**

            *设置counts属性。这个方法由容器自动调用。

            */

           public void setCounts(int c)

           {

                  this.counts=c;

           }

          

           /**

            *覆盖doStartTag方法

            */

            public int doStartTag() throws JspTagException 

            {  

                System.out.println("doStartTag");

                if(counts>0)

                {

                    return EVAL_BODY_TAG;

                }

                else

                {

                     return SKIP_BODY;

                }

        }

       

        /**

         *覆盖doAfterBody方法

         */

        public int doAfterBody() throws JspTagException

        {

            System.out.println("doAfterBody"+counts);

            if(counts>1)

            {

                   counts--;

                   return EVAL_BODY_TAG;

             } 

             else

             {

                return SKIP_BODY;

             }

        }

       

       /**

         *覆盖doEndTag方法

         */

        public int doEndTag() throws JspTagException

        {

             System.out.println("doEndTag");

            try

            { 

                 if(bodyContent != null) 

                 {

                      bodyContent.writeOut(bodyContent.getEnclosingWriter());

                 }

            }

            catch(java.io.IOException e)

            {

                   throw new JspTagException("IO Error: " + e.getMessage()); 

            }  

            return EVAL_PAGE; 

        }

       

         public void doInitBody() throws JspTagException{

          System.out.println("doInitBody");

         }

         public void setBodyContent(BodyContent bodyContent)

         {  

              System.out.println("setBodyContent");

              this.bodyContent=bodyContent;

         }

    }

    教材例程14-8,同mytag.tld文件,加上下述一段即可。

      <tag> 

            <name>loop</name>

           <tag-class>com.jspdev.ch14.BodyTagExample</tag-class>

           <body-content>jsp</body-content>

            <attribute>

                 <name>counts</name>

                 <required>true</required>

                 <rtexprvalue>true</rtexprvalue>

          </attribute>

        </tag>

    教材例程14-10,bodytag.jsp文件,调用上述标签。

    <%@ taglib uri="/demotag" prefix="bodytag" %>
    <html>
    <head>
    <title>body tag</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>
    <body>
    <HR>
    <bodytag:loop counts="5"> 
    现在的时间是: <%=new java.util.Date()%><BR>
    </bodytag:loop> 
    <HR> 
    </BODY> 
    </HTML>

    运行结果如下图所示。

    14.4 多个标签的嵌套 上一节 下一节 本章开头

      类似于循环的嵌套和开关语句,在实际开发中,往往需要多个标签嵌套在一起完成特定的任务。教材中例举的例子如下:

    <mt:switch value="test">
      <mt:case value="test1">
        my value is test1
      </mt:case>
      <mt:case value="test">
        my value is test
      </mt:case>
    </mt:switch>

      上面的标签中,<mt:switch>为父标签,<mt:case>为子标签,一个父标签可以嵌套多个子标签和HTML、Scriptlets等。

    教材例程14-11,IfTag.java文件。

    package com.jspdev.ch14;

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.Hashtable;

    import java.io.Writer;

    import java.io.IOException;

     

    /**

     *if Tag

     *usage:<tag:if value=true>

     *      ...

     *      </tag:if>

     */

    public class IfTag extends BodyTagSupport

    {

           private boolean value;

           /**

            *设置属性的值。

            */

           public void setValue(boolean value)

           {

                  this.value=value;

           }

          

           /**

            *doStartTag方法,如果value为true,那么

            *就计算tagbody的值,否则不计算body的值。

            */

           public int doStartTag() throws JspTagException

           {

                  if(value)

            {

                System.out.println("value is true");

               return EVAL_BODY_INCLUDE;

             } 

             else

             {

               System.out.println("value is false");

                return SKIP_BODY;

             }

          }

            

        

        /**

         *覆盖doEndTag方法

         */

        public int doEndTag() throws JspTagException

        {

            try

            { 

                 if(bodyContent != null) 

                 {

                      bodyContent.writeOut(bodyContent.getEnclosingWriter());

                 }

            }

            catch(java.io.IOException e)

            {

                   throw new JspTagException("IO Error: " + e.getMessage()); 

            }  

            return EVAL_PAGE; 

        }

         

    }

    教材例程14-12,OutTag.java文件。IfTag中嵌套了一个子标签,子标签的Java文件为OutTag.java。

    package com.jspdev.ch14;

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.Hashtable;

    import java.io.Writer;

    import java.io.IOException;

     

    public class OutTag extends TagSupport

    {

           private Object value;     

          

        /**

         *覆盖doStartTag方法

         */

       public void setValue(Object value)

       {

          this.value=value;

       }

      

        public int doStartTag() throws JspTagException {

           return EVAL_BODY_INCLUDE;

        }

       

        /**

         *覆盖doEndTag方法

         */

           public int doEndTag()throws JspTagException

           {

     

                  try

                  {

                         System.out.println(value);

                         pageContext.getOut().write(value.toString());

                        

                  }

                  catch(IOException ex)

                  {

                         throw new JspTagException("Fatal error:hello tag conld not write to JSP out");

                  }

                  return EVAL_PAGE;

           }

         

    }

    教材例程14-13,同mytag.tld文件,加上下述一段即可。

       <tag>

            <name>if</name>

           <tag-class>com.jspdev.ch14.IfTag</tag-class>

           <body-content>jsp</body-content>

            <attribute>

                 <name>value</name>

                 <required>true</required>

                 <rtexprvalue>true</rtexprvalue>

          </attribute>

       </tag>

       <tag>

            <name>out</name>

           <tag-class>com.jspdev.ch14.OutTag</tag-class>

           <body-content>jsp</body-content>

            <attribute>

                 <name>value</name>

                 <required>true</required>

                 <rtexprvalue>true</rtexprvalue>

          </attribute>

       </tag>

    教材例程14-14,cortag.jsp文件,调用上述标签。

    <%@ taglib uri="/demotag" prefix="mt" %>
    <html>
    <head>
    <title>vcorwork tag</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
    </head>
    <body>
    <HR>
    协作标签<br>
    <%
    boolean test=true;
    String outValue="HelloWorld!";
    %>
    <mt:if value="<%=test%>">
    <mt:out value="<%=outValue%>">
    这是mt:out...>打印出的内容。
    </mt:out>
    </mt:if>
    <HR> 
    <mt:if value="false">
    <mt:out value="<%=outValue%>">
    这些内容会显示在客户端。
    </mt:out>
    </mt:if>
    <br>
    </BODY> 
    </HTML>

      运行结果如下图:

    14.开发迭代的标签库 上一节 下一节 本章开头

      在没有迭代标签的时候,要循环输出内容到网页,一般采用while语句进行循环,如:

     while(rst.next())
     {
        out.println("bookName:"+rst.getString("bookName"));
        out.println("<br>"); 
     }

      上述循环结构可以用迭代标签替代。

      如果要实现内容的迭代输出,需要开发两个类,一个类实现BodyTagSupport接口,另一个类扩展TagExtraInfo类。TagExtraInfo旨在提供标签运行时的信息。

    教材例程14-15,IterateTag.java文件 ,实现BodyTagSupport类的接口

    package com.jspdev.ch14;

    import javax.servlet.jsp.*;

    import javax.servlet.jsp.tagext.*;

    import java.util.*;

     

    public class IterateTag extends BodyTagSupport

    {

           /**

            *Tag的属性

            */

           private String name;

           //it为要迭代的对象

           private Iterator it;

           //type表示it中对象的类型

           private String type;

     

           /**

            *设置属性collection

            */

           public void setCollection(Collection collection)

           {

                  if(collection.size()>0)

                  it=collection.iterator();

           }

           public void setName(String name)

           {

                  this.name=name;

           }

           public void setType(String type)

           {

                  this.type=type;

           }

           /**

            *如果it属性为null,那么忽略计算tagbody

            */

           public int doStartTag()throws JspTagException

           {

                  if(it==null)

                         return SKIP_BODY;

                  else

                         return continueNext(it);

           }

          

           public int doAfterBody()throws JspTagException

           {

                  return continueNext(it);

           }

          

           public int doEndTag()throws JspTagException

           {

                  try

                  {

                         if(bodyContent!=null)

                         bodyContent.writeOut(bodyContent.getEnclosingWriter());

                  }

                  catch(java.io.IOException e)

                  {

                  }

                 

                  return EVAL_PAGE;

           }

           /**

            *保护方法,用于把it.next()设置为pagecontext的属性

            */

           protected int continueNext(Iterator it)throws JspTagException

           {

                  if(it.hasNext())

                  {

                         pageContext.setAttribute(name,it.next(),PageContext.PAGE_SCOPE);

                         return EVAL_BODY_TAG;

                  }

                  else

                  {

                         return SKIP_BODY;

                  }

           }

    }

    教材例程14-16,IterateTEI.java文件,为表示信息的标签类。

    package com.jspdev.ch14;

    import javax.servlet.jsp.tagext.*;

    //TagExtraInfo用于提供一些在标签翻译时相关的信息。

    public class IterateTEI extends TagExtraInfo

    {

           public IterateTEI()

           {

                  super();

           }

          

           public VariableInfo[] getVariableInfo(TagData data)

           {

                  return new VariableInfo[]

                  {

                         new VariableInfo(

                                data.getAttributeString("name"),

                                data.getAttributeString("type"),

                                true,

                                VariableInfo.NESTED

                         ),

                  };

           }

    }

      其中AT_BEGIN, NESTED, AT_END是标签扩展信息类(TEI)的VariableInfo中定义,如果设置为AT_BEGIN,变量在当前动作元素的开始标记之后就对调用者可见。如果此属性设置为AT_END,那么变量则在结束标记之后可见。NESTED 说明它仅在开始和结束标记之间可见。

    教材例程14-17,同mytag.tld文件,加上下述一段即可。

       <tag>

          <name>iterate</name>

          <tag-class>com.jspdev.ch14.IterateTag</tag-class>

          <tei-class>com.jspdev.ch14.IterateTEI</tei-class>

          <body-content>jsp</body-content>

          <attribute>

                 <name>collection</name>

                 <required>true</required>

                 <rtexprvalue>true</rtexprvalue>

          </attribute>

          <attribute>

                 <name>name</name>

                 <required>true</required>

          </attribute>

          <attribute>

                 <name>type</name>

                 <required>true</required>

          </attribute>

      </tag>

    教材例程14-18,iterator.jsp文件,调用上述标签。

    <%@ taglib uri="/demotag" prefix="mt"%>

    <%

           com.jspdev.ch14.Company comp=new com.jspdev.ch14.Company();

           comp.setName("huayuan");

           com.jspdev.ch14.Contact contact1=new com.jspdev.ch14.Contact();

           contact1.setName("bar ,foo");

           contact1.setEmail("dd@tsinghua.eud.cn");

           contact1.setPhone("2975349875");

           contact1.setComment("java programe");

          

           com.jspdev.ch14.Contact contact2=new com.jspdev.ch14.Contact();

           contact2.setName("bar ,foo");

           contact2.setEmail("dd@tsinghua.eud.cn");

           contact2.setPhone("2975349875");

           contact2.setComment("java programe");

          

           com.jspdev.ch14.Contact contact3=new com.jspdev.ch14.Contact();

           contact3.setName("bar ,foodf");

           contact3.setEmail("dd@tsinghua.euddfdf.cn");

           contact3.setPhone("2975349875dd");

           contact3.setComment("java progrdfame");

          

           comp.addContact(contact1);

           comp.addContact(contact2); 

           comp.addContact(contact3);

           request.setAttribute("company",comp);

    %>

    <html>

    <head>

    <title>迭代标签演示</title>

    </head>

    <body>

    <jsp:useBean id="company" scope="request" type="com.jspdev.ch14.Company"/>

     

    <font size=+2>我的一些和<b>

    <jsp:getProperty name="company" property="name"/>

    公司联系</b>

    </font>

    <hr>

    <table border=1>

    <tr>

    <td>姓名</td>

    <td>电话</td>

    <td>email</td>

    <td>备注</td>

    </tr>

    <mt:iterate name="contact" collection="<%=company.getContacts()%>" type="com.jspdev.ch14.Contact">

    <tr>

           <td>

           <jsp:getProperty name="contact" property="name"/>

           </td>

           <td>

           <jsp:getProperty name="contact" property="phone"/>

           </td>

           <td>

           <jsp:getProperty name="contact" property="email"/>

           <td>

           <jsp:getProperty name="contact" property="comment"/>

           </td>

    </tr>

    </mt:iterate>

    </table>

    <hr>

    </body>

    </html>

      运行结果如下图:

    14.6 SimpleTag开发 上一节 本章开头

      SimpleTag有自己的生命周期,最主要就是doTag方法。

      1) 每次遇到标签,容器构造一个SimpleTag的实例,这个构造方法没有参数。和红典的标签一样,SimpleTag不能缓冲,故不能重用,每次都需要构造新的实例。
      2) setJspContext()、setParent(): 只有这个标签在另一个标签之内时,才调用setParent()方法;
      3) 设置属性:调用每个属性的setter方法;
      4) setJspBody();
      5) doTag(): 所有标签的逻辑、迭代和Body计算,都在这个方法中;
      6) return,当doTag方法返回时,所有的参数被锁定。
     

    教材例程14-19,HelloWorldSimpleTag.java文件。

    package com.jspdev.ch14;

     

    import javax.servlet.jsp.JspException;

    import javax.servlet.jsp.tagext.SimpleTagSupport;

    import java.io.IOException;

     

    public class HelloWorldSimpleTag extends SimpleTagSupport {

       

        public void doTag() throws JspException, IOException {

           getJspContext().getOut().write( "<table border=1><tr bgcolor=9944cc><td>simpeltag测试</tr></td><tr tr=cc44cc><td>helloWorld!</td></tr></table>" );

        }

    }

    教材例程14-20,同mytag.tld文件,加上下述一段即可。

      <tag>

           <description>Outputs Hello, World</description>

            <name>helloWorld</name>

           <tag-class>com.jspdev.ch14.HelloWorldSimpleTag</tag-class>

           <body-content>empty</body-content>

      </tag>

    教材例程14-21,simple_tag.jsp文件,调用上述标签。

    <%@ page contentType="text/html; charset=gb2312" language="java" %>

    <%@ taglib uri="/demotag" prefix="mt"%>

    <html>

      <head>

        <title>JSP 2.0 Examples - 简单的标签</title>

      </head>

      <body>

        <h1>JSP 2.0 Examples - 简单的标签</h1>

        <hr>

        <p>这里是一个非常简单的标签.</p>

        <br>

        <b><u>Result:</u></b>

        <mt:helloWorld/>

      </body>

    </html>


    展开全文
  • 第二个问题是freemarker如何导入jsp标签并使用。 目录结构: project -src/main/java -src/main/resource -mapper -public(静态资源文件) -template(freemarker页面) -src/test/java -Maven xxx -JRE xxx ...
  • 自定义标签库

    千次阅读 2011-04-08 16:51:00
    自定义标签库并不是 JSP 2 才出现的,JSP 1.1 版中已经增加了自定义标签库规范,自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。 为什么要使用自定义...
    自定义标签库并不是 JSP 2 才出现的,JSP 1.1 版中已经增加了自定义标签库规范,自定义标签库是一种非常优秀的表现层组件技术。通过使用自定义标签库,可以在简单的标签中封装复杂的功能。 为什么要使用自定义标签呢?主要是为了取代丑陋的 JSP 脚本。在 HTML 页面中插入 JSP 脚本有如下几个坏处: JSP 脚本非常丑陋,难以阅读。 JSP 脚本和 HTML 代码混杂,维护成本高。 HTML 页面中嵌入 JSP 脚本,导致美工人员难以参与开发。 出于以上三点的考虑,我们需要一种可在页面中使用的标签,这种标签具有和 HTML 标签类似的语法,但由可以完成 JSP 脚本的功能——这种标签就是 JSP 自定义标签。 在 JSP1.1 规范中开发自定义标签库比较复杂,JSP 2 规范简化了标签库的开发,在 JSP 2 中开发标签库只需如下几个步骤: 开发自定义标签处理类; 建立一个 *.tld 文件,每个 *.tld 文件对应一个标签库,每个标签库对应多个标签; 在 JSP 文件中使用自定义标签。 开发自定义标签类 标签库和实际开发标签库是非常重要的技术,通常来说,初学者、普通开发人员自己开发标签库的机会很少,但如果希望成为高级程序员,或者希望开发通用框架,就需要大量开发自定义标签了。所有的 MVC 框架,如 Struts 2、SpringMVC、JSF 等都提供了丰富的自定义标签。 当我们在 JSP 页面使用一个简单的标签时,底层实际上由标签处理类提供支持,从而可以使用简单的标签来封装复杂的功能,从而使团队更好地协作开发(能让美工人员更好地参与 JSP 页面的开发)。 早期 JSP 自定义标签类开发过程略微复杂一些,但 JSP 2 已经简化了这个过程,它只要自定义标签类都必须继承一个父类:javax.servlet.jsp.tagext.SimpleTagSupport,除此之外,JSP 自定义标签类还有如下要求。 如果标签类包含属性,每个属性都有对应的 getter 和 setter 方法。 重写 doTag() 方法,这个方法负责生成页面内容。 下面开发一个最简单的自定义标签,该标签负责在页面上输出 HelloWorld。 // 标签处理类,继承 SimpleTagSupport 父类 public class HelloWorldTag extends SimpleTagSupport { // 重写 doTag 方法,该方法在标签结束生成页面内容 public void doTag()throws JspException, IOException { // 获取页面输出流,并输出字符串 getJspContext().getOut().write("Hello World"); } } 上面这个标签处理类非常简单,它继承了 SimpleTagSupport 父类,并重写 doTag() 方法,而 doTag() 方法则负责输出页面内容。该标签没有属性,因此无须提供 setter 和 getter 方法。 -------------------------------------------------------------------------------- 回页首 建立 TLD 文件 TLD 是 Tag Library Definition 的缩写,即标签库定义,文件的后缀是 tld,每个 TLD 文件对应一个标签库,一个标签库中可包含多个标签,TLD 文件也称为标签库定义文件。 标签库定义文件的根元素是 taglib,它可以包含多个 tag 子元素,每个 tag 子元素都定义一个标签。通常我们可以到 Web 容器下复制一个标签库定义文件,并在此基础上进行修改即可。例如 Tomcat6.0,在 webapps/examples/WEB-INF/jsp2 路径下包含了一个 jsp2-example-taglib.tld 文件,这就是示范用的标签库定义文件。 将该文件复制到 Web 应用的 WEB-INF/ 路径,或 WEB-INF 的任意子路径下,并对该文件进行简单修改,修改后的 mytaglib.tld 文件代码如下: 
     
     
     
      1.0
      
     
      mytaglib
      
      
     
      http://www.crazyit.org/mytaglib
      
      
      
       
      
       helloWorld
       
       
      
       lee.HelloWorldTag
       
       
      
       empty
       
      
     上面标签库定义文件也是一个标准的 XML 文件,该 XML 文件的根元素是 taglib 元素,因此我们每次编写标签库定义文件都直接添加该元素即可。 taglib 下有三个子元素: tlib-version:指定该标签库实现的版本,这是一个作为标识的内部版本号,对程序没有太大的作用。 short-name:该标签库的默认短名,该名称通常也没有太大的用处。 uri:这个属性非常重要,它指定该标签库的 URI,相当于指定该标签库的唯一标识。如上粗体字代码所示,JSP 页面中使用标签库时就是根据该 URI 属性来定位标签库的。 除此之外,taglib 元素下可以包含多个 tag 元素,每个 tag 元素定义一个标签,tag 元素下至少应包含如下三个子元素: name:该标签库的名称,这个属性很重要,JSP 页面中就是根据该名称来使用此标签的。 tag-class:指定标签的处理类,毋庸置疑,这个属性非常重要,指定了标签由哪个 Java 类来处理。 body-content:这个属性也很重要,它指定标签体内容。该元素的值可以是如下几个: tagdependent:指定标签处理类自己负责处理标签体。 empty:指定该标签只能作用空标签使用。 scriptless:指定该标签的标签体可以是静态 HTML 元素,表达式语言,但不允许出现 JSP 脚本。 JSP:指定该标签的标签体可以使用 JSP 脚本。 实际上由于 JSP 2 规范不再推荐使用 JSP 脚本,所以 JSP 2 自定义标签的标签体中不能包含 JSP 脚本。所以实际上 body-content 元素的值不可以是 JSP。 定义了上面的标签库定义文件后,将标签库文件放在 Web 应用的 WEB-INF 路径,或任意子路径下,Java Web 规范会自动加载该文件,则该文件定义的标签库也将生效。 -------------------------------------------------------------------------------- 回页首 使用标签库 在 JSP 页面中确定指定标签需要 2 点: 标签库 URI:确定使用哪个标签库。 标签名:确定使用哪个标签。 使用标签库分成以下两个步骤: 导入标签库:使用 taglib 编译指令导入标签库,就是将标签库和指定前缀关联起来。 使用标签:在 JSP 页面中使用自定义标签。 taglib 的语法格式如下: <%@ taglib uri="tagliburi" prefix="tagPrefix" %> 其中 uri 属性确定标签库的 URI,这个 URI 可以确定一个标签库。而 prefix 属性指定标签库前缀,即所有使用该前缀的标签将由此标签库处理。 使用标签的语法格式如下: 
     
      
     如果该标签没有标签体,则可以使用如下语法格式: 
     上面使用标签的语法里都包含了设置属性值,前面我们介绍的 HelloWorldTag 标签没有任何属性,所以使用该标签只需用 
     即可。其中 mytag 是 taglib 指令为标签库指定的前缀,而 helloWorld 是标签名。 下面是使用 helloWorld 标签的 JSP 页面代码: <%@ page contentType="text/html; charset=GBK"%> 
     <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>   
    自定义标签示范   
    

    下面显示的是自定义标签中的内容


    上面页面中第一行粗体字代码指定了 http://www.crazyit.org/mytaglib 标签库的前缀为 mytag,第二行粗体字代码表明使用 mytag 前缀对应标签库里的 helloWorld 标签。浏览该页面将看到如图 1 所示效果: 图 1. 简单标签 -------------------------------------------------------------------------------- 回页首 带属性的标签 前面的简单标签既没有属性,也没有标签体,用法、功能都比较简单。实际上还有如下两种常用的标签: 带属性的标签。 带标签体的标签。 正如前面介绍的,带属性标签必须为每个属性提供对应的 setter 和 getter 方法。带属性标签的配置方法与简单标签也略有差别,下面介绍一个带属性标签的示例: public class QueryTag extends SimpleTagSupport { //标签的属性 private String driver; private String url; private String user; private String pass; private String sql; //执行数据库访问的对象 private Connection conn = null; private Statement stmt = null; private ResultSet rs = null; private ResultSetMetaData rsmd = null; //标签属性driver的setter方法 public void setDriver(String driver) { this.driver = driver; } //标签属性url的setter方法 public void setUrl(String url) { this.url = url; } //标签属性user的setter方法 public void setUser(String user) { this.user = user; } //标签属性pass的setter方法 public void setPass(String pass) { this.pass = pass; } //标签属性driver的getter方法 public String getDriver() { return (this.driver); } //标签属性url的getter方法 public String getUrl() { return (this.url); } //标签属性user的getter方法 public String getUser() { return (this.user); } //标签属性pass的getter方法 public String getPass() { return (this.pass); } //标签属性sql的getter方法 public String getSql() { return (this.sql); } //标签属性sql的setter方法 public void setSql(String sql) { this.sql = sql; } public void doTag()throws JspException, IOException { try { //注册驱动 Class.forName(driver); //获取数据库连接 conn = DriverManager.getConnection(url,user,pass); //创建Statement对象 stmt = conn.createStatement(); //执行查询 rs = stmt.executeQuery(sql); rsmd = rs.getMetaData(); //获取列数目 int columnCount = rsmd.getColumnCount(); //获取页面输出流 Writer out = getJspContext().getOut(); //在页面输出表格 out.write(" query lee.QueryTag empty driver true true url true true user true true pass true true sql true true iterator lee.IteratorTag scriptless collection true true item true true 带标签体的标签-迭代器标签

    带标签体的标签-迭代器标签


    a = new ArrayList (); a.add("hello"); a.add("world"); a.add("java"); //将List对象放入page范围内 pageContext.setAttribute("a" , a); %>
    "); //遍历结果集 while (rs.next()) { out.write("
    "); //逐列输出查询到的数据 for (int i = 1 ; i <= columnCount ; i++ ) { out.write("
    "); out.write(rs.getString(i)); out.write("
    "); } out.write(" "); } } catch(ClassNotFoundException cnfe) { cnfe.printStackTrace(); throw new JspException("自定义标签错误" + cnfe.getMessage()); } catch (SQLException ex) { ex.printStackTrace(); throw new JspException("自定义标签错误" + ex.getMessage()); } finally { //关闭结果集 try { if (rs != null) rs.close(); if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException sqle) { sqle.printStackTrace(); } } } } 上面这个标签稍微复杂一点,它包含了 5 个属性,如程序中粗体字代码所示,则程序需要为这 5 个属性提供 setter 和 getter 方法。 该标签输出的内容依然由 doTag() 方法决定,该方法会根据 SQL 语句查询数据库,并将查询结果显示在当前页面中。 对于有属性的标签,需要为 tag 元素增加 attribute 子元素,每个 attribute 子元素定义一个属性,attribue 子元素通常还需要指定如下几个子元素: name:设置属性名,子元素的值是字符串内容。 required:设置该属性是否为不需属性,该子元素的值是 true 或 false。 fragment:设置该属性是否支持 JSP 脚本、表达式等动态内容,子元素的值是 true 或 false。 为了配置上面的 QueryTag 标签,我们需要在 mytaglib.tld 文件中增加如下配置片段: 上面 5 行粗体字代码分别为该标签配置了 driver、url、user、pass 和 sql 等 5 个属性,并指定这 5 个属性都是必填属性、而且属性值支持动态内容。 配置完毕后,就可在页面中使用标签,先导入标签库,然后使用标签。使用标签的 JSP 页面片段如下: <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%> ... 在浏览器中浏览该页面,效果如图 2 所示。 图 2. 使用带属性的标签执行查询 图 2 中看到从数据库里查询到 2 条记录,当然这也需要底层 javaee 数据库里包含 newsinf 数据表,且该数据表里包含这两条记录才行。 在 JSP 页面中只需要使用简单的标签,即可完成“复杂”的功能:执行数据库查询,并将查询结果在页面上以表格形式显示。这也正是自定义标签库的目的——以简单的标签,隐藏复杂的逻辑。 当然,并不推荐在标签处理类中访问数据库,因为标签库是表现层组件,它不应该包含任何业务逻辑实现代码,更不应该执行数据库访问,它只应该负责显示逻辑。 -------------------------------------------------------------------------------- 回页首 带标签体的标签 带标签体的标签,可以在标签内嵌入其他内容(包括静态的 HTML 内容和动态的 JSP 内容),通常用于完成一些逻辑运算,例如判断和循环等。下面以一个迭代器标签为示例,介绍带标签体标签的开发过程。 一样先定义一个标签处理类,该标签处理类的代码如下: public class IteratorTag extends SimpleTagSupport { //标签属性,用于指定需要被迭代的集合 private String collection; //标签属性,指定迭代集合元素,为集合元素指定的名称 private String item; //collection属性的setter和getter方法 public void setCollection(String collection) { this.collection = collection; } public String getCollection() { return this.collection; } //item属性的setter和getter方法 public void setItem(String item) { this.item = item; } public String getItem() { return this.item; } //标签的处理方法,简单标签处理类只需要重写doTag方法 public void doTag() throws JspException, IOException { //从page scope中获取属性名为collection的集合 Collection itemList = (Collection)getJspContext(). getAttribute(collection); //遍历集合 for (Object s : itemList) { //将集合的元素设置到page 范围 getJspContext().setAttribute(item, s ); //输出标签体 getJspBody().invoke(null); } } } 上面标签处理类与前面处理类并没有太大的不同,该处理类包含 2 个属性,并为这两个属性提供了 setter 和 getter 方法。标签处理类的 doTag 方法首先从 page 范围内获取了指定名称的 Collection 对象,然后遍历 Collection 对象的元素,每次遍历都调用了 getJspBody() 方法,如程序中粗体字代码所示,该方法返回该标签所包含的标签体:JspFragment 对象,执行该对象的 invoke() 方法,即可输出标签体内容。该标签的作用是:遍历指定集合,每遍历一个集合元素,即输出标签体一次。 因为该标签的标签体不为空,配置该标签时指定 body-content 为 scriptless,该标签的配置代码片段如下代码所示: 上面配置片段中粗体字代码指定该标签的标签体可以是静态 HTML 内容,也可以是表达式语言。 为了测试在 JSP 页面中使用该标签的效果,我们首先把一个 List 对象设置成 page 范围的属性,然后使用该标签来迭代输出 List 集合的全部元素。 JSP 页面代码如下: <%@ page import="java.util.*"%> <%@ page contentType="text/html; charset=GBK"%> <%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%> <% //创建一个List对象 List
    ${pageScope.item}
    上面页面代码中粗体字代码即可实现通过 iterator 标签来遍历指定集合,浏览该页面即看到如图 3 所示界面: 图 3. 带标签体的标签 图 3 显示了使用 iterator 标签遍历集合元素的效果,从 iteratorTag.jsp 页面的代码来看,使用 iterator 标签遍历集合元素比使用 JSP 脚本遍历集合元素要优雅得多,这就是自定义标签的魅力。 实际上 JSTL 标签库提供了一套功能非常强大标签,例如普通的输出标签,像我们刚刚介绍的迭代器标签,还有用于分支判断的标签等等,JSTL(JSP 标准标签库)都有非常完善的实现。除此之外,Apache 下还有一套 DisplayTags 的标签库实现,做得也非常不错。
    展开全文
  • Taglib指令,其实就是定义一个标签库以及自定义标签的前缀。 比如struts中支持的标签库,html标签库、bean标签库、logic标签库。 其中的具体的实现方式,我们不过多介绍,我们给大家从宏观的角度以及解决其中的疑难...
  • 自己写的自定义标签库,实现JSTL常用的功能。
  • 打包自定义标签库 把自定义的标签打到一个jar包中,就是要把标签处理类的字节码和标签库描述文件按照一定的存放方式添加到一个jar包中。 使用jar命令来创建jar文件: jar cvf mytaglib_0.9.jar META-INF com 完成...

    打包自定义标签库

    把自定义的标签打到一个jar包中,就是要把标签处理类的字节码和标签库描述文件按照一定的存放方式添加到一个jar包中。

    使用jar命令来创建jar文件:
    jar cvf mytaglib_0.9.jar  META-INF  com

    完成这两个步骤之后,一个自定义标签库jar包就打好了,可以把它添加到任何想使用这个标签库的Web应用程序的WEB-INF/lib目录下使用了。

    自定义分页标签

    分页标签的使用方式如下:
    <q:pager pageNo="当前页号" pageSize="每页要显示的记录数" recordCount="总记录数" url="要跳转的URI" />

    通过给这个标签传入当前页号、每页要显示的记录数、总记录数和要跳转的URI,这个标签就可以生成翻页的HTML元素。

    标签处理类

    这个标签只是通过指定属性值就可以生成所有的翻页元素,因此这个标签不需要主体,可以直接继承自TagSupport类:public class PagerTag extends TagSupport {...}

    然后为这个标签定义4个属性,给它们提供setter方法,以便使用标签时,从外部传值进来。

    最主要的逻辑实现都是在doStartTag()方法中,首先通过总记录数和每页要显示的记录数计算出总页数:
    int pageCount = (recordCount + pageSize - 1) / pageSize;

    编写要输出到响应的StringBuilder实例。

    把请求对象中获取的所有请求参数都作为隐藏表单域(<input type=“hidden”>)生成到一个form表单中:

    生成翻页的HTML元素。这一段逻辑稍微复杂一些。

    生成“总记录数和总页数”

    是否要显示“上一页”超链接的逻辑处理。

    如果总页数超过5页,显示“…”

    当前页和它附近页的显示处理

    如果总页数比当前页数超过2页,显示“...”

    是否要显示“下一页”超链接的逻辑处理

    在标签库描述符文件描述这个标签的信息

    在页面中使用该分页标签

    用taglib指令引用该标签库描述文件:
    <%@ taglib uri="http://blog.csdn.net/qjyong/tags/pager"prefix="q"%>

    为该分页标签准备好一些样式,让翻页元素更美观:

    用代码片段显示数据

    调用分页标签

    创建一个TestPagerTagServlet的Servlet,用来准备测试数据,并为分页标签准备好参数值,然后转发到测试页。

     

    展开全文
  • 打包自定义标签库

    2012-11-22 18:33:37
    打包自定义标签库 把自定义的标签打到一个jar包中,就是要把标签处理类的字节码和标签库描述文件按照一定的存放方式添加到一个jar包中。 使用jar命令来创建jar文件: jar cvf mytaglib_0.9.jar META-INF com ...
  • 自定义标签库开发

    千次阅读 2011-11-08 21:24:08
    自定义标签库开发 自定义标签简介 自定义标签主要用于移除Jsp页面中的java代码。 快速入门:使用自定义标签输出客户机IP 移除jsp页面中的java代码,只需要完成两个步骤: 编写一个实现Tag接口的Java类,并覆盖...
  • JSP自定义标签库

    千次阅读 2011-11-09 10:04:39
     自定义标签库分为传统标签,简单标签,和标签文件.三者区别在于一个比一个简单.实现细节大致相同.实现原理也大致相同.下面简单说说实现过程. Tag接口:普通标签体接口.继承与JspTag. 把pageContext传给...
  • JSP自定义标签库和函数

    千次阅读 2017-06-28 22:37:07
    一、基础知识1. 常见的自定义标签库有哪些? jstl中的c、fn、fmt等 <%@ taglib prefix="fmt" uri
  • 自定义标签实现分页查询

    千次阅读 2018-06-11 21:42:19
    自定义标签库和自定义标签类(实现了tagSupport) 第二步、前端页面使用自定义标签 导入自定义标签库 使用自定义标签 第三步、后台实现 后台实现的过程就是将查询到的信息及分页信息封装到page对象中相应...
  • jsp页面自定义标签使用,以及Java后台实现自定义标签功能方法
  •  自定义标签库是jsp api下的内容。通常一个自定义标签会包含3部分内容:标签处理类,tld标签描述文件,jsp文件(使用)。  *标签处理类:继承自 SimpleTagSupport类即可,重写其doTag()方法。我们在页面写了一...
  • 打包自定义标签库   把自定义的标签打到一个jar包中,就是要把标签处理类的字节码和标签库描述文件按照一定的存放方式添加到一个jar包中。具体做法如下。   把标签处理类字节码和标签库描述文件按如下所示结构...
  • 自定义标签库并打成jar包

    千次阅读 2015-04-23 00:20:40
    在所需要的网页中添加自己写好的标签库,声明如 调用写好的标签如 进入.tld配置文件中,寻找此标签名所对应实现的标签类,调用你已经写好的类 (2)在些自定义类时注意 JspWriter与PrintWriter的关系 ...
  • 自定义标签实现按钮权限

    千次阅读 2017-08-19 20:15:52
    背景:项目原有权限的颗粒度是精确到菜单上的,但是到了项目的尾声,客户提出要求,要为按钮也要加上权限,因为当初对数据设计的原因以及项目架构的原因,项目不支持第三方的...于是关于jsp自定义标签实现按钮权限的
  • 近期在开发中遇到一种需求:根据...这样,就需要用到自定义标签了。要定义Struts2的自定义标签,只需三步: 定义一个Component类,并继承自org.apache.struts2.components.Component; 定义一个Tag类,并继承自import
  • 在JSP中,规范简化了标签库的开发,在JSP2中开发自定义标签只需如下三个步骤: 一、开发自定义标签处理类 二、建立一个*.tld文件 三、在JSP文件中使用自定义标签 自定义标签类应该继承一个父类:javax.servlet....
  • 自定义标签库(一)

    千次阅读 2005-11-22 16:16:00
    使用自定义标签库,我们可以提高WEB应用的模块性、复用性、科维护性等等。相信对于标准标签库和Struts提供的标签库,我们是可以使用自如了,但是对于如何针对自己的应用来定制标签库,可能还是不太了解。下面介绍...
  • 利用JSP自定义标签实现分页。操作和维护非常简单、方便,相比servlet~

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 128,144
精华内容 51,257
关键字:

自定义标签库实现方式