`

JSP:自定义标签——开发实例

阅读更多
【实例109】  开发带属性的标签:helloTagHaveProp
  本实例中开发的标签在实例108的helloTag标签上作出改进,开发目标是在helloTag标签上增加两个属性fontSize和fontColor,fontSize用于设置字体大小,fontColor用于设置文字的颜色。
  (1)第一步:开发标签实现类。
  helloTagHaveProp.java
  package hello;
  import javax.servlet.jsp.JspWriter;
  import javax.servlet.jsp.tagext.TagSupport;
  public class helloTagHaveProp extends TagSupport {
    private String fontSize="3";//字体大小,默认3号
    private String fontColor="#000000";//字体颜色,默认黑色
    //----标签开始时调用此方法-------
    public int doStartTag(){
        try{
            JspWriter out=pageContext.getOut();
            out.print("标签开始了。<font color=\""+fontColor +
                 "\" size=\""+fontSize+"\">hello!</font>");
        }catch(Exception e){
            System.out.println(e);
        }
        return EVAL_BODY_INCLUDE;
    }
    //----标签结束时调用此方法-------
    public int doEndTag(){
        try{
            JspWriter out=pageContext.getOut();
            out.print("标签结束了。");
        }catch(Exception e){
            System.out.println(e);
        }
        return EVAL_PAGE;
    }  
    public String getFontColor() { 
        return fontColor;
    }
    public void setFontColor(String fontColor) {
        this.fontColor = fontColor;
    }
    public String getFontSize() {
        return fontSize;
    }
    public void setFontSize(String fontSize) {
        this.fontSize = fontSize;
      }
  }

  (2)第二步:编写标签描述tld文件。这里在myTag.tld文件中增加内容,在<taglib>与</taglib>之间增加的内容如下:
  <!-- helloTagHaveProp-->
  <tag>
     <!-- 标签名称-->
     <name>helloTagHaveProp</name>
     <!-- 标签对应的处理类-->
     <tag-class>hello.helloTagHaveProp</tag-class>
     <!-- 标签体内容,没有标签体则设为empty-->
     <body-content>empty</body-content>
     <!-- 标签的属性声明-->
     <attribute>
      <name>fontSize</name>
      <required>false</required>
     </attribute>
     <attribute>
      <name>fontColor</name>
      <required>false</required>
     </attribute>
  </tag>

  其中,name为属性的名称,required设置此属性是否必须设置,如果为true则在JSP页面中使用此标签时,必须给标签的这个属性赋值。

  (3)第三步:在Web应用的web.xml文件中声明标签库引用。本例与实例108使用同一个tld文件,故不必再修改。

  (4)第四步:在JSP页面中声明并调用标签。
  useHelloTagHaveProp.jsp
  <%@ taglib uri="/myTag" prefix="myTag" %>
  <%@ page contentType="text/html;charset=GB2312" %>
  <html>
    <head>
   <title>一个简单的自定义标签</title>
   </head>
   <body>
   下面是应用这个简单的自定义标签的结果:<br>
  <myTag:helloTagHaveProp fontSize="5"/><br>
  <myTag:helloTagHaveProp fontSize="4" fontColor="red"/>
    </body>
  </html>

  程序的运行结果如图13-3所示。




三、 开发带标签体的标签
  要开发带标签体的标签,可实现BodyTag接口,也可从BodyTag接口的实现类BodyTagSupport继承,为简化开发,推荐从BodyTagSupport类继承开发。
  编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag(),他们执行顺序如下:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,如果返回EVAL_BODY_ INCLUDE则继续执行;如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,而直接执行doEndTag()方法。

  setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,

  EVAL_PAGE或SKIP_PAGE。如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。

  【实例110】  开发带标签体的标签:bodyTag1
  本实例将要开发一个带标签体的标签bodyTag1,这个标签有一个属性countNum,用于设置输出标签体内容的次数,输出内容为当前的系统时间。

  (1)第一步:开发标签实现类。
  BodyTag1.java
  package body;
  import javax.servlet.jsp.JspWriter;
  import javax.servlet.jsp.tagext.BodyTagSupport;
  public class bodyTag1 extends BodyTagSupport{
    private int countNum=0;//循环显示时间的次数
    private int currentNum=1;//当前执行次数
    //----标签开始时调用此方法-------
    public int doStartTag(){
        try{
            JspWriter out=pageContext.getOut();
            out.print("标签开始了:<br>");
            if(countNum>0)
                return EVAL_BODY_TAG;
            else
                return SKIP_BODY;
           
        }catch(Exception e){
            System.out.println(e);
            return SKIP_BODY;
        }
    }
    //----标签体执行完后调用此方法----
    public int doAfterBody(){
        try{
         JspWriter out=pageContext.getOut();
         out.print("第"+currentNum+"次执行标签体。标签体执行完毕。<br>");
         if(countNum>1){//如果还需要执行标签体
             countNum--;
             currentNum++;
             return EVAL_BODY_TAG;
         }else return SKIP_BODY;
        }catch(Exception e){
            System.out.println(e);
            return SKIP_BODY;
        }
    }
    //----标签结束时调用此方法-------
    public int doEndTag(){
        try{
            JspWriter out=pageContext.getOut();
            //----输出标签体的内容----
            bodyContent.writeOut(bodyContent.getEnclosingWriter());
            out.print("标签结束了。");
        }catch(Exception e){
            System.out.println(e);
        }
        return EVAL_PAGE;
    }  
    public int getCountNum() {
        return countNum;
    }
    public void setCountNum(int countNum) {
        this.countNum = countNum;
        this.currentNum=1;
      }
  }

  执行标签体并不会直接输出标签体中的内容,因此本实例在doEndTag()方法中一次性把执行的结果输出。

  (2)第二步:编写标签描述tld文件。
  因为本章所有实例共用一个Web应用,故本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的内容如下:
  <!-- bodyTag1-->
  <tag>
  <!-- 标签名称-->
  <name>bodyTag1</name>
  <!-- 标签对应的处理类-->
  <tag-class>body.bodyTag1</tag-class>
  <!-- 标签体内容,有标签体则设为jsp-->
  <body-content>jsp</body-content>
  <!-- 标签的属性声明-->
  <attribute>
   <name>countNum</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  </tag>

  对于属性countNum的声明中,<required>设置为true,表示此属性为必输项;<rtexprvalue>设置为true,表示标签体支持运行时的表达式取值,如果为false则表示标签体为一个静态文本,默认情况下设置为true。

  (3)第三步:在Web应用的web.xml文件中声明标签库引用。
  同样,本例与实例108使用同一个tld文件,不必再修改。

  (4)第四步:在JSP页面中声明并调用标签。
  UseBodyTag1.jsp
  <%@ taglib uri="/myTag" prefix="myTag" %>
  <%@ page contentType="text/html;charset=GB2312" %>
  <%@ page import="java.util.Date" %>
  <html>
    <head>
    <title>开发带有标签体的标签</title>
    </head>
    <body>
  下面是应用这个带有属性的自定义标签的结果:<br>
  <myTag:bodyTag1 countNum="6">
   现在的时间是:<%=new Date()%><br>
  </myTag:bodyTag1>
   </body>
  </html>
  该程序的运行结果如图13-4所示。



【实例111】  开发嵌套的标签:haveChildTag
  实际工程中往往需要多个标签来配合完成一定的功能,嵌套的标签存在父子关系,其中,父为外层标签,子为内层标签。本实例将用两个简单的标签来演示,父标签则作出逻辑判断,如果isOutput属性为true,则输出实例108中的标签helloTag;如果为false,则不输出。

  (1)第一步:开发标签实现类。
  内层的标签helloTag在实例108中已有,此处不再列出。
  haveChildTag.java
  package hello;
  import javax.servlet.jsp.tagext.BodyTagSupport;
    public class haveChildTag extends BodyTagSupport {
      private boolean isOutput;//是否输出子标签内容
      //----标签开始时调用此方法-------
      public int doStartTag(){
          if(isOutput)
              return EVAL_BODY_INCLUDE;
          else return SKIP_BODY;
      }
      //----标签结束时调用此方法-------
      public int doEndTag(){
          try{
              if(bodyContent!=null)
                bodyContent.writeOut(bodyContent.getEnclosingWriter());
          }catch(Exception e){
              System.out.println(e);
          }
          return EVAL_PAGE;
      }  
      public boolean getIsOutput() {
          return isOutput;
      }
      public void setIsOutput(boolean isOutput) {
          this.isOutput = isOutput;
      }
  }

  (2)第二步:编写标签描述tld文件。
  本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加的如下内容:
  <!-- haveChildTag-->
  <tag>
  <!-- 标签名称-->
  <name>haveChildTag</name>
  <!-- 标签对应的处理类-->
  <tag-class>hello.haveChildTag</tag-class>
  <!-- 标签体内容,有标签体则设为jsp-->
  <body-content>jsp</body-content>
  <!-- 标签的属性声明-->
  <attribute>
   <name>isOutput</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  </tag>

  (3)第三步:在Web应用的web.xml文件中声明标签库引用。
  同样,本例与本章前面的实例使用同一个tld文件,此处不必再修改。

  (4)第四步:在JSP页面中声明并调用标签。
  useHaveChildTag.jsp
  <%@ taglib uri="/myTag" prefix="myTag" %>
  <%@ page contentType="text/html;charset=GB2312" %>
  <%@ page import="java.util.Date" %>
  <html>
   <head>
   <title>开发嵌套的标签</title>
   </head>
    <body>
  输出子标签时的结果:<br>
  <myTag:haveChildTag isOutput="true">
   <myTag:helloTag/>
  </myTag:haveChildTag><br>
  不输出子标签时的结果:<br>
  <myTag:haveChildTag isOutput="false">
   <myTag:helloTag/>
  </myTag:haveChildTag><br>
   </body>
  </html>
  该程序的运行结果如图13-5所示。



《JSP网络编程从实践到实践》原码下载地址:http://shop.csai.cn/itbook/itbookinfo.asp?lbbh=10051575    

  五、 开发迭代的标签
  【实例112】  开发迭代的标签:iterateTag
  对于集合对象的Iterator类对象,在JSP的Java代码中需要用while循环或for循环来输出,难于维护,且可复用性不好,程序员总是在大量地做这样的工作,这时可以考虑用迭代的标签来开发,需要输出数据时只须在JSP页面中声明标签即可。

  开发迭代的标签,需要设计两个Java类:标签实现类和表示标签信息的类。本实例中标签实现类为iterateTag.java,表示标签信息的类为IterateTEI.java。开发迭代的标签可实现IterationTag接口,也可从TagSupport类或BodyTagSupport类继承,由于BodyTagSupport类继承自TagSupport类,而TagSupport类又实现了IterationTag接口,为简化开发,直接从BodyTagSupport类继承即可。

  (1)第一步:开发标签实现类和表示标签信息的类。
  iterateTag.java
  package body;
  import java.util.Collection;
  import java.util.Iterator;
  import javax.servlet.jsp.tagext.BodyTagSupport;
  public class iterateTag extends BodyTagSupport{
      private String name;//在pageContext中标识的一个属性名
      private Iterator it;//要迭代的对象
      private String type;//it中对象的类型
      public void setCollection(Collection collection){
          if(collection.size()>0)
              it=collection.iterator();
      }
   
      //----标签开始时调用此方法-------
    public int doStartTag(){
        if(it==null) return SKIP_BODY;
        else return continueNext(it);
    }
    //----标签体执行完后调用此方法----
    public int doAfterBody(){
        return continueNext(it);
    }
    //----标签结束时调用此方法-------
      public int doEndTag(){
          try{
              if(bodyContent!=null)
                bodyContent.writeOut(bodyContent.getEnclosingWriter());
         }catch(Exception e){
              System.out.println(e);
          }
          return EVAL_PAGE;
      } 
      //----迭代----
      protected int continueNext(Iterator it){
          if(it.hasNext()){
              pageContext.setAttribute(name,it.next(),pageContext.PAGE_SCOPE);
              return EVAL_BODY_TAG;
          }else return SKIP_BODY;
      }
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public String getType() {
          return type;
      }
      public void setType(String type) {
          this.type = type;
      }
  }

  在标签实现类中,有3个属性:name、type和it。其中,name代表在pageContext中标识一个属性的名字;type代表待迭代内容的数据类型;it为要迭代的内容。在doStartTag()方法中,如果it不为null,就开始迭代,迭代时调用continueNext()方法。
  IterateTEI.java
  package body;
  import javax.servlet.jsp.tagext.TagData;
  import javax.servlet.jsp.tagext.TagExtraInfo;
  import javax.servlet.jsp.tagext.VariableInfo;
  //----提供标签翻译时的一些相关信息----
  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)             
            };
        }
    }
  VariableInfo类中有几个常量,具体的含义为:
  NESTED:标签中的参数在标签开始到标签结束之间是有效的。
  AT_BEGIN:标签中的参数在标签开始到使用它的JSP页面结束是有效的。
  AT_END:标签中的参数在标签的结束到使用它的JSP页面结束是有效的。

  (2)第二步:编写标签描述tld文件。本例在myTag.tld文件中增加内容。在<taglib>与</taglib>之间增加如下内容:
     <!-- iterateTag-->
      <tag>
      <!-- 标签名称-->
      <name>iterateTag</name>
      <!-- 标签对应的处理类-->
      <tag-class>body.iterateTag</tag-class>
      <tei-class>body.IterateTEI</tei-class>
      <!-- 标签体内容,有标签体则设为jsp-->
      <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>
  </taglib>

  (3)第三步:在Web应用的web.xml文件中声明标签库引用。同样,本例与本章前面的实例使用同一个tld文件,因此不必再修改。

  (4)第四步:在JSP页面中声明并调用标签。
  <%@ taglib uri="/myTag" prefix="myTag" %>
  <%@ page contentType="text/html;charset=GB2312" %>
  <%@ page import="java.util.ArrayList"%>
    <head>
    <title>开发迭代的标签</title>
    </head>
   <body>
    开发一个迭代的标签,输出结果:<br>
    <%//----------设置一个ArrayList对象的初始值----------
   ArrayList testCol=new ArrayList();
   testCol.add("邓佳容");
   testCol.add("黄婧");
   testCol.add("邓子云");
   request.setAttribute("testCol",testCol);
   %>
    <myTag:iterateTag name="testColOne" collection="<%=testCol%>" type="String">
     输出一个值:<%=testColOne.toString()%><br>
   </myTag:iterateTag>
   </body>
  </html>
  该程序的运行结果如图13-6所示。


分享到:
评论

相关推荐

    JSP实例开发源码——Noka tag 软件标签.zip

    JSP自定义标签的开发过程涉及以下几个关键步骤: 1. **创建标签处理类**:这些是Java类,实现了`javax.servlet.jsp.tagext.Tag`接口或其子接口。它们包含标签的行为逻辑,当JSP页面解析到相应的标签时,这些类会被...

    JSTL自定义标签实例解析

    JavaServer Pages Standard Tag Library (JSTL) 是一套标准的标签库,用于简化JSP开发。JSTL允许开发者使用预定义的标签来处理常见任务,如迭代、条件判断、XML处理等。本文将深入讲解如何创建并使用JSTL自定义标签...

    java自定义标签的开发与应用.doc

    Java自定义标签的开发与应用主要涉及到JSP的扩展机制,允许开发者根据需求创建自己的标签库,以增强页面的表现力和可复用性。在JSTL提供的标准标签库不能满足特定需求时,自定义标签成为了解决问题的关键。 10.1 ...

    jsp标签的详细使用说明

    3. **在JSP页面中使用自定义标签**:通过`自定义标签库的URI" prefix="前缀" %&gt; `指令引入自定义标签库,并使用`前缀:标签名`的形式调用自定义标签。 #### 知识点三:示例分析——HelloTag自定义标签 以给定的`...

    jsp实例开发——购物车

    【JSP实例开发——购物车】是一个典型的网上商城系统中的重要组成部分,主要涉及网页动态编程技术JSP(Java Server Pages)以及购物车功能的实现。在这个实例中,我们将深入探讨如何利用JSP来构建一个简单但功能齐全...

    JSP实例开发源码——图书管理系统(java+mssql).zip

    在这个系统中,JSP页面通常作为视图,Java Servlet或JSP自定义标签作为控制器,而数据库操作则由模型层完成。 在数据库方面,Microsoft SQL Server是一款强大的关系型数据库管理系统,支持多种数据类型和高级查询...

    jsp 自定义标签

    ### JSP自定义标签详解 #### 一、概述 JSP (Java Server Pages) 技术为网页开发者提供了一个简洁而强大的方式来处理服务器端逻辑与动态内容的生成。其中,自定义标签(Custom Tags)作为JSP的一个重要特性,极大地...

    JSP实例开发源码——图片浏览小程序(java+applet).zip

    综上所述,这个"JSP实例开发源码——图片浏览小程序(java+applet)"涵盖了Web开发的多个核心知识点,包括JSP、JavaBeans、数据库操作、Applet技术、MVC模式、文件操作以及安全性考虑。通过学习和分析这个实例,开发者...

    jsp学习笔记——初学者的选择

    【JSP学习笔记——初学者的选择】 JSP(JavaServer Pages)是JavaEE平台中用于构建动态网页的应用技术。作为初学者,理解JSP的基本概念和技术特性至关重要。 1. **为何选择JSP?** JSP的出现主要是为了解决...

    JSP核心技术——JSP引擎内幕(2010).pdf

    ### JSP核心技术——JSP引擎内幕 #### 一、JSP引擎的工作原理 JSP(Java Server Pages)是一种基于Java的服务器端脚本技术,它允许开发者将动态内容嵌入到HTML网页中。JSP的核心功能是通过JSP引擎来实现的。JSP...

    JSP源码——网页中文本框自校验的标签_input.zip

    在IT行业中,JSP(JavaServer Pages)是一种用于创建动态网页的技术,它允许开发者将Java代码...通过学习这个案例,开发者可以深入理解JSP自定义标签的工作原理,并将其应用到自己的项目中,提高开发效率和代码质量。

    jsp实例开发1

    在JSP中,可以通过Servlet或自定义标签库(JSTL)来实现控制器的功能。 4. **商品展示**:商品信息通常从服务器端获取并传递到客户端。这可以通过JSP的内置对象`request`或`session`来实现,或者使用EL(Expression...

    网络程序设计——JSP从入门到精通

    - 使用JSP自定义标签提高代码可读性和复用性。 - 结合Servlet和JavaBean实现数据处理和状态管理。 通过学习《网络程序设计——JSP从入门到精通》,读者可以系统地掌握JSP的各个方面,从基础语法到高级特性,再到...

    JSP实例开发源码——阳光酒店管理系统(javaapplet+SQL).zip

    【JSP实例开发源码——阳光酒店管理系统(javaapplet+SQL)】 本压缩包提供了一个基于JSP技术的阳光酒店管理系统的完整源码,结合了JavaApplet和SQL数据库技术,为酒店运营提供了全面的信息化解决方案。以下是该系统...

    面向开发人员之ASP.NET开发技术系列课程(4):JSP开发人员篇——如何转向ASP.NET开发

    本课程是"面向开发人员之ASP.NET开发技术系列课程"的一部分,特别是针对已经熟悉JSP开发的人员设计的,旨在帮助他们顺利过渡到ASP.NET平台,利用其强大的特性和工具进行高效Web应用程序开发。在这个过程中,我们将...

    Jsp——入门

    3. `taglib指令`:引入自定义标签库,比如Struts、JSF等框架的标签。 **JSP动作(Actions)**: 1. `jsp:include`:运行时包含一个文件,可以带有请求参数。 2. `jsp:forward`:将请求转发到另一个页面。 3. `jsp:...

    Web程序设计——JSPppt

    3. **JSP自定义标签**: 开发者可以创建自己的标签库,提高代码的可读性和可复用性,类似于HTML的自定义标签。 4. **JSP 2.0及以上版本的新特性**: 包括引入了JSR 152的EL 2.0,增强了EL的功能;引入了scriptlet的...

    Tag的使用<JSP 2.0新特性>

    本实例将深入探讨`Tag`的使用,以及如何通过JSP 2.0新特性来简化自定义标签的开发过程。 自定义标签的核心在于Tag Handler,这是处理特定标签行为的Java类。在JSP 2.0之前,创建自定义标签需要编写复杂的TLD(Tag ...

    从零开始——JSP动态网页制作基础培训教程-源代码.rar)

    JSTL是一组标准标签库,简化了JSP开发,提供了包括核心、SQL、XML和函数等不同领域的标签。 8. **Servlet与JSP的关系** JSP最终会被转换为Servlet,Servlet负责处理请求,JSP则专注于展示。两者结合使用,可以...

    JSP企业类实例开发源码——灵智电子政务网站系统.zip

    灵智电子政务网站系统是一个基于JSP技术的企业级应用实例,旨在提供一套完善的政府信息化解决方案。这个源码项目涵盖了从用户界面设计、后端数据处理到服务器端逻辑的全面开发,为开发者提供了一个学习和实践JSP编程...

Global site tag (gtag.js) - Google Analytics