cc彩球网登录 – 程序员的那点事!

首页 > 编程资料 > Java语言 > 正文

[zt]JSP标记学习笔记 itpride(原作)

浏览次数:次 2003年01月06日 作者:eclipse 字号:

JSP标记学习笔记    itpride(原作) 
  
关键字     JSP标记 
  

  
JSP标记学习笔记

ginkou.fly  2002-9-18

1.  概述

1)  什么是JSP标记

顾名思义,JSP标记就是在JSP文件中使用的标记。它类似于html语法中的标记,像head 、table 。通过在JSP文件中引用它(就像使用html标记那样),可以更方便的实现对Java 代码模块的重用。

2)  为什么要使用JSP 标记技术(与javabean相比)

好处:

J JSP 标记可以处理JSP正文的内容,比如改变文本显示样式;而javabean不可以。

J JSP标记接口简单,易于使用,也易于开发和维护。

坏处:

L JSP标记在进行设置时要比javabean复杂很多,体现在JSP标记库描述文件(*.tld)的配置上。

L JSP标记实现的功能远不如javabean强大。

L 当前只要JSP1.1支持JSP标记,而JSP1.0和1.1都支持对Bean的使用。

2.  SP标记的开发简介。

JSP标记的开发需要编写2种独立的文件。一种是定义标记功能的java类文件,一种是将xml元素名称(标记)映射到标记实现的标记库描述符文件。

⑴ 编写标记处理程序类文件

需要继承javax.servlet.jsp.tagext.TagSupport类;

简单示例:

//文件名ExampleTag.java

import javax.servlet.jsp.*&#59;

import javax.servlet.jsp.tagext.*&#59;

import java.io.*&#59;

       

public class ExampleTag extends TagSupport {

       //程序的执行起始点

         public int doStartTag() {  

              try {

                     JspWriter out=pageContext.getOut()&#59;

                     out.print(“Custom tag example”)&#59;

        }catch (IOException ioe) {

                     System.out.println(“Error in ExampleTag : “ + ioe)&#59;

        }

            return(SKIP_BODY)&#59; //当标记包括的内容为空时返回SKIP_BODY,表示标记功能

//已执行完成

      }

}

  编译好的class文件将位于服务器的的特定位置。

⑵ 编写标记库描述符文件

将标记名和其代表的功能实现联系在一起。

  简单示例:

  <!--文件名:csajsp-taglib.tld-->;

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

<!DOCTYPE taglib 

PUBLIC “-//Sun Microsystem,Inc.//DTD JSP Tag Library 1.1//EN”

http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd>;

//以上是标准的文件头

//以下是标签库描述

<tlibversion>;1.0</tlibversion>; //Tag 库的版本

<jspversion>;1.1</jspversion>; //Jsp 库的版本

<shortname>;csajsp</shortname>;//自定义标记前缀名

<uri>;</uri>; //标记描述符文件的uri,可以是空

<info>;My custom tag!</info>; //标记库的描述信息

//以下定义新标记

<tag>;

       <name>;example</name>; //自定义的标记名

       <tagclass>;tags.ExampleTag</tagclass>;//定位标签处理类文件

<info>;Simplest example</info>;//描述信息

<bodycontent>;EMPTY</bodycontent>; // 不处理Jsp文件正文内容

</tag>;

</taglib>;

此文件将配置在服务器的特定位置

⑶ 使用以上自定义的标记

<!--文件名:simpleExample.jsp-->;

<!DOCTYPE HTML PUBLIC  “- // W3C//DTD HTML 4.0 Transitional //EN”>;

<HTML>;

<HEAD>;

<%@ taglib uri = “csajsp-taglib.tld” prefix = “csajsp” %>; //进行标记使用声明

<TITLE>;<csajsp:example />;<TITLE>;

<LINK REL=STYLESHEET HREF=”JSP-styles.css”

                         TYPE=”text/css”>;

<HEAD>;

<BODY>;

<H1>;<csajsp:example />;<H1>; /使用标记

<csajsp:example />;

</BODY>;

</HTML>;

这样最终在在浏览器上输出为

  Custom tag example

3.  深入的JSP标记开发

⑴ 添加标记属性

在标记处理类中可以通过函数setAttribute(String value) 为jsp标记分配属性,这样标记处理程序根据获取的属性值来实现相关功能。

比如 private String message = “Default Message”&#59;

public void setMessage(String message) {

        this.message=message&#59;

  }

注意:属性名message是小写的,设置函数中的Message是大写的。

◆与之相关的在tld文件中需要在tag元素中添加如下元素

<tag>;



<attribute>;

 <name>;message</name>; //属性名

 <required>;false</requied>; //属性值是否必须提供。False表示不必,存在缺省值。

 <rtexprvalue>;true</rtexprvalue>;//ture表示属性值可以使用jsp表达式,false表示禁

//止使用

</attribute>;



</tag>;

◆对应jsp文件中引用为:<prefix : name message = “ Hello!” />;

⑵ 使用标记正文

 即是在标记中使用一些包含jsp脚本元素、文本等的内容,这些内容由jsp引擎处理。

 形式如下:

 <prefix : tagname>; body(正文内容) <prefix : tagname>;

 在处理jsp标记的正文前,将会调用处理程序的doStartTag()方法,此时要在此方法中返回EVAL_BODY_INCLUDE 以表明包含有标记正文;处理完后,将会调用doEndTag()方法,此后要让jsp引擎继续处理后面的页面,得返回EVAL_PAGE,否则返回SKIP_PAGE。

 ◆对应在tld文件中需要在tag元素中添加如下元素

 <tag>;

 …

 <bodycontent>;JSP</bodycontent>; //表明包含正文

 …

 </tag>;

 另外:可以设置一些条件来判断是否包含正文的,如下:

 public int doStartTag() {

       ServletRequest request = pageContext.getRequest()&#59;

      String debugFlag = request .getParameter(“debug”)&#59;

      If ((debugFlag!=null) &amp;&amp; (!debugFlag.equalsIgnoreCase(“false”))) {

          Return (EVAL_BODY_INCLUDE)&#59;

       }

       else {

           return(SKIP_BODY)&#59;

       }

  }

这样只有在url尾部给出请求参数值debug = true,才会显示标记正文的内容。这样可以隐藏一些调试信息。

⑶ 对标记正文进行处理

  jsp的标记可以对包含的正文进行处理(修改),然后再输出。这需要标记处理类继承BodyTagSupport类(TagSupport类的继承)。这个类提供了2个重要的方法用于正文处理。

  → doAfterBody:默认执行的方法,在此方法中包含正文的处理过程。

→ getBodyContent:返回BodyContent类型的的对象,此对象包含了有关标记正文的信息。

 BodyContent类型包含的重要方法:

→ getEnclosingWriter:返回JspWriter方法,输出内容。

→ getString:返回包含全部jsp标记正文的字符串。

注意:这里和⑵中介绍的输出jsp标记正文的方式不一样。前者的输出是先由jsp引擎解释,这里是在jsp标记处理程序中直接输出到给浏览器。

另外,在doAferBody中返回SKIP_BODY,表示终止标记正文处理;若返回的是EVAL_BODY_TAG,将会再一次调用doAferBody方法,重新处理标记正文,直到返回SKIP_BODY为止。

示例:

→标记处理程序片:

//下面的程序片将调用一个filter方法,此方法用于把jsp正文中的字符< >; “ &amp; 分别用&amp;it&#59;  &amp;gt&#59;  &amp;guot&#59;  &amp;amp&#59;来代替。以使浏览器按字符原样输出,不进行解释。

public class FillterTag extends BodyTagSupport {

       public  int doAfterBody() {

          BodyContent body=getBodyContent()&#59;

        String filteredBody=ServletUtilities.filter(body.getString())&#59; //将正文得到的字符串过滤

    Try {

       JspWriter out=body.getEnclosingWriter()&#59;

out.print(filteredBody)&#59; //输出过滤后的文本

}catch(IOException ioe) {

        System.out.println(“Error in FilterTag: “ + ioe)&#59;

}

return(SKIP_BODY)&#59; //终止jsp正文处理

              }

→标记符描述文件片

   …

  <tag>;

  <name>;filter</name>;

  <tagclass>;tags.FilterTag</tagclass>;

  <bodycontent>;JSP</bodycontent>;

  </tag>;

    …

→jsp文件片

   <csajsp:filter>;

  <STRONG>;I love you!</STRONG>;
;

  <EM>;I love you!<EM>;

  </csajsp:filter>;

  这样,在浏览器中输出的标记正文应当是

<STRONG>;I love you!</STRONG>;
;

<EM>;I love you!<EM>;

 而不是

 I love you!

 I love you!

  ⑶使用jsp嵌套标记。

     可以对多个JSP标记进行嵌套引用,这样子标记就可以访问和存储父标记的数据和方法。

        子标记访问父标记需要使用BodyTagSupport类中的 findAccetorWithClass方法。注意它只能查找临近的父标记。

     假如在jsp文件中如下的嵌套引用:

     <!- - 此嵌套标记模拟条件判断- ->;

     <csajsp:if>;

      <csajsp:condition>;true</csajsp:condition>;

      <csajsp:then>;Condition was true</csajsp:then>;

      <csajsp:else>;Condition was false</csajsp:else>;

     </csajsp:if>;

     相应的标记处理程序片:

     →对于if标记,执行类如下:

     public class IfTag extends TagSupport {

          private boolean condition &#59;

        private Boolean hasCondition = flase &#59;

        public void setCondition(Boolean condition) { //设置判断条件的真假;condition子标

//记调用

                  this.condition = condition &#59;

                  hasCondition = true &#59;

        }

public Boolean getCondition() {           //获取判断条件的真假then 、else子标

//记调用

                  return(condition) &#59;

              }

              public void setHasCondition(Boolean flag) {  //判断if标记后是否存在条件,由

//condition子标记调用

                  this.hasCondition = flag &#59;

              }

              public Boolean getHasCondition() {         //获取是否存在判断条件的信息,由

//then、else标记调用

                  return(hasCondition) &#59;

              }

              public int doStartTag() {

                  return(EVAL_BODY_INCLUDE)      //包含子标记

              }

        }

 

→那么对于condition等其它子标记的处理程序,需要获取父标记处理程序对象:

IfTag  parent=(IfTag)  findAncestorWithClass(this,IfTag.class)

之后就可以操作父标记处理程序的相应方法。

示例:(对于condition标记)

public class IfConditionTag extends BodyTagSupport {

    ifTag parent = (IfTag)findAncestorWithClass(this,IfTag.class)&#59; //获取父标记对应的对象

If (parent = = null) {

       Throw new JspTagException(“condition not inside it”)&#59;

}

return(EVAL_BODY_TAG)&#59;

}

 

public int doAfterBody() {

       ifTag parent = (IfTag) findAncestorWithClass(this , IfTag.class) &#59;

    String bodyString = getBodyContent() . getString() &#59;

    If (bodyString.trim().equals(“true”)) {

           Parent.setCondition(true)           //访问父标记处理类中的方法

    }else {

           parent.setCondition(false) &#59;

    }

return(SKIP_BODY) &#59;

}

}

其余标记类和此相似。

4.  小结

对于一些不太复杂和功能单一的逻辑描述,需要传递的参数要求不高时,使用JSP标记,要方便的多。对于大多数的商业逻辑应用,还是使用bean要好的多,也宜于servlet控制。

 

这个东东是俺学习 人邮 出的Servletlet与JSP核心技术》时随手写下的。里面的程序还没具体配置过。过段时间弄了再搞篇实验体会吧。
 




 cinc 回复于:2002-09-23 20:35:26

tag 是 jsp 里一个很强大的功能。
在 tag 基础上开发出的 struts 是 MVC 结构的 java web 开发框架。
和 taglibs 一样 structs 也是 jakarta 的一个项目




 jeff123 回复于:2003-01-06 20:16:01

老兄,taglib是那么简单地和javabean对比的吗?从你的手记也能看出来,你刚刚学习tag的应用,还早呢。