`
igogogo9
  • 浏览: 247770 次
  • 性别: Icon_minigender_1
  • 来自: 海口市
社区版块
存档分类
最新评论

JSP中自定义标记符的使用

阅读更多
摘要
   在JSP中有一种机制,可以让你在JSP页面中插入与HTML类似的标记。本文介绍JSP定制标记的基本概念和构成,以及如何开发和应用JSP定制标记。

关键字
JSP,XML,TLD,标记符

什么是标记
使用HTML语言我们可以这样去编辑我们的网页:

   <HTML>

    <HEAD>

<TITLE>

HELLO  WORLD

</TITLE>

        </HEAD>

        <BODY>

HELLO WORLD

</BODY>

</HTML>

在这里我们把</HEAD>,<TITLE>,<BODY>称为标记。HTML 标记( HTML Markup)是HTML文档的控制语言,用于指定浏览器显示和打印文档的方式.它是用小于号"<"和大于号">"括起来的短语和符号,如 <Html>、</Body>等。许多HTMl标记以成对的方式出现,如<TITLE>< /TITLE>、<Body></Body> 等。在JSP中我们也可以定制自己的标记,以供JSP页面使用,如下例所示

<!—login.jsp-->

<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>

<html>

      <head>

           <title>login</title>

      </head>

      <body>

        <tagclass:login width="200" height= "100" >

           </tagclass:login>

      </body>

</html>

在上例中</tagclass:login>就是一个JSP定制标记符。widtht、height是这个标记的属性。<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>是一个标记库定义指令,在稍后我们将会讨论。在JSP中定制标记符,实质上就是以标记的形式封装了一个俱有独立功能的Java类。标记的使用减少了直接嵌入JSP页面的Java代码,方便了页面的布局,并且有利于代码的复用,提高了开发的效率。

JSP服务器解析标记的过程
那么当一个标记被嵌入JSP页面后,JSP服务器是如何对这个标记进行解析的呢?各对象的含义如下所示:

Client:   表示客户端。

JSP-Server:JSP服务器。

JSP-Page:JSP页面。

TLD:   标记库描述文件,定义标记和标记的各种属性和处理文件等。

TagClass   标记处理程序

当一个用户访问一个JSP页面时,这个请求被发送到JSP服务器,JSP服务器会根据这个请求去调用相应的页面,如果这个页面中有自定义的标记, JSP服务就会根据页面指令<%@ taglib>去访问TLD得到处理程序的相关信息,接着调用该处理程序的构造器方法,启动标记符处理程序,并读取标记符的属性和相应值。对每个没有设置属性的,调用相应的set方法。当标记符第一次使用时,它的任何属性都不会做过设置,因此对每个属性都调用set方法。属性设置完以后,JSP服务器调用处理程序的doStartTag(),然后再调用doEndTag()方法。最后JSP服务器会继续处理剩下的页面,在页面结尾调用release ()方法,清理占用的所有资源。

TLD文件
TLD(TLD:Tag Library Descriptor标记库描述符)文件,标准的XML格式的标记定义文件,被用来存放标记符的信息,下面就是一个典型的TLD文件。

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

<!—XML的版本及其字符集-->





<!DOCTYPE taglib

      PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

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

<!—文档类型定义-->





<taglib>

<!—此标记说明我们开始描述一个标记库-->





  <tlibversion>1.0</tlibversion>

 <!—标记库的版本-->





  <jspversion>1.1</jspversion>

 <!—所使用的JSP的版本-->





 <shortname>tagclass</shortname>

 <!—缺省的名称-->





  <tag>

     <name>login</name>

    <!—标记的名称-->





<tagclass>

tagclass.login.login

<!—处理这个Tag的相应的类的名称-->



</tagclass>

     <info>

      <!—对本标记符的描述-->



     </info>

<attribute>

<!—开始定义标记的属性-->



          <name>height</name>

       <!—属性的名称-->



          <required>true</required>

       <!—表示这个属性是不是必须的-->



          <rtexprvalue>true</rtexprvalue>

<!—表示这个属性是否可以用JSP的程序段的结果输出-->

      </attribute>

<attribute>

          <name>width</name>

          <required>true</required>

          <rtexprvalue>true</rtexprvalue>

      </attribute>

    </tag>

</taglib>

在这个TLD文件中定义了只有一个标记符的标记符库,这个名为login的标记符会调用一个Applet以验证用户的合法性。处理这个标记的类就是 tagclass.login.login。width、height是这个标记的两个属性。属性是在使用标记符时作为参数发送的值。我们可以在上面的示例中增加几个标记,也可以为每个标记添加几个属性。我们开发标记符库时不一定非要从头开始,自己编写一个全新TLD。我们可以使用某个集成的开发的环境,也可以修改上面的例子。

TagLib指令
那么当JSP服务器在解析一个标记符时,它是如何定义一个标记库的呢?这就是TagLib指令的主要责任。

Taglib 指令

定义一个标记库以及其自定义标记的前缀.

JSP 语法

<%@ taglib uri="URIToTagLibrary" prefix="tagPrefix" %>

例子
<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>

<html>

      <head>

           <title>login</title>

      </head>

      <body>

        <tagclass:login width="200" height= "100" >

           </tagclass:login>

      </body>

</html>

描述

<% @ taglib %>指令声明此JSP文件使用了自定义的标记,同时引用标记库,

也指定了他们的标记的前缀。 你必须在使用自定义标记之前使用<% @ taglib %>指令。

属性

uri="URIToTagLibrary" :Uniform Resource Identifier (URI)根据标记的前缀对自定义的标记进行唯一的命名,URI可以是一个相对或绝对的路径。
  prefix="tagPrefix":在自定义标记之前的前缀。如上例中的</tagclass:login>

标记符的处理程序(Tag handle)
我们还是以一个例子来看下如何实现一个Tag handle。首先是看一下它的类图:



让我们再看一下它的代码:

package  tagclass.login;

import javax.servlet.jsp.tagext.TagSupport;

import javax.servlet.jsp.*;

import java.io.*;

public class login extends TagSupport

{

      public login()

     {

             super();

      }

      public int doStartTag() throws JspTagException

     {

                JspWriter out = pageContext.getOut();

                try

                {

                        out.println("<APPLET CODEBASE=applet/login/ CODE=login.class width=200 height=100 > </APPLET>");

}

                catch(Exception e)

                {



                }

             return SKIP_BODY;

}

publicc int doEndTag()throws JsptagException

{

     return EVAL_PAGE;

}

       public void release()

       {

                 super.release();

       }

      public void setWidth(String language)

      {

             this.width = width;

      }

      public String getWidth()

      {

             return this.width;

      }

      public void setHeight(String height)

      {

          this.height=height;

      }

      public String getHeight()

      {

          return this.height;

      }

      private String width;

      private String height;

}

从以上我们可以看出,实现一个简单的标记符处理程序有几个要求:①增加一个类,使之继承 java.Servlet.jsp.tagext.TagSupport类。这个类提供了java.Servlet.jsp.tagext.Tag接口所要求的所有的方法。另外,还需要使用一些基本的API,使JSP容器能够调用我们自己提供的标记符处理程序。②必须为每个标记符属性分别创建一个 get<attribute>和set<attribute>方法,JSP容器需要使用这些方法处理程序传递参数。③要为标记符处理程序创建一个构造器和自毁器。JSP需要使用构造器启动处理程序。自毁器是在realease()方法中定义的。在处理程序的生命周期结束时,需要调用自毁器释放所占用的资源。④创建两个名为doStartTag()和doEndTag()的方法,执行具体的处理和输出动作。这两个方法是在处理自定义标记符的起始位置和结束位置调用的。它们的返回值是在Tag Interface里定义的静态int,这几个静态值分别是:

SKIP_BODY隐含0  :跳过了开始和结束标签之间的代码。

EVAL_BODY_INCLUDE隐含1:将body的内容输出到存在的输出流中

SKIP_PAGE隐含5 : 忽略剩下的页面。

EVAL_PAGE隐含6:继续执行下面的页

  当然标记符也有它自己的缺点。很不方便的封装过程,有限的功能。对于一些不太复杂和功能单一的逻辑描述,需要传递的参数要求不高时,使用JSP标记,要方便的多。对于大多数的商业逻辑应用,还是使用bean要好的多,也宜于servlet控制。

附录:文章中所用示例的完整代码
JSP代码:login.jsp
<%@ taglib uri="/tlds/taglib.tld" prefix="tagclass" %>

<html>

     <head>

           <title></title>

     </head>

     <body>

           <tagclass:login width="200" height= "100" >

           </tagclass:login>

     </body>

</html>

标记符描述库:taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE taglib

      PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"

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

<taglib>

  <tlibversion>1.0</tlibversion>

  <jspversion>1.1</jspversion>

 <shortname>tagclass</shortname>

  <tag>

     <name>login</name>

<tagclass>

tagclass.login.login

</tagclass>

     <info>

    </info>

<attribute>

          <name>height</name>

          <required>true</required>

          <rtexprvalue>true</rtexprvalue>

      </attribute>

<attribute>

          <name>width</name>

          <required>true</required>

          <rtexprvalue>true</rtexprvalue>

      </attribute>

    </tag>

</taglib>

标记符处理程序:login.java
package  tagclass.login;

import javax.servlet.jsp.tagext.TagSupport;

import javax.servlet.jsp.*;

import java.io.*;

public class login extends TagSupport

{

      public login()

     {

             super();

      }

      public int doStartTag() throws JspTagException

     {

                JspWriter out = pageContext.getOut();

                try

                {

                        out.println("<APPLET CODEBASE=applet/login/ CODE=login.class width=200 height=100 > </APPLET>");

}

                catch(Exception e)

                {



                }

             return SKIP_BODY;

}

publicc int doEndTag()throws JsptagException

{

     return EVAL_PAGE;

}

       public void release()

       {

                 super.release();

       }

      public void setWidth(String language)

      {

             this.width = width;

      }

      public String getWidth()

      {

             return this.width;

      }

      public void setHeight(String height)

      {

          this.height=height;

      }

      public String getHeight()

      {

          return this.height;

      }

      private String width;

      private String height;

}

标记符处理程序中所使用的Applet : login.java
import java.awt.*;

import java.awt.event.*;

import java.applet.*;

public class login extends Applet implements ActionListener

{

    private String s_username;

    private String s_userpassword;

    private Button b_ok;

    private Button b_register;

    private Label l_username;

    private Label l_userpassword;

    private TextField t_username;

    private TextField t_userpassword;

    private GridLayout g_gridlayout;

    public void init()

    {

       b_ok=new Button("ok");

       b_register=new Button("register");

       l_username= new Label("name");

       l_userpassword=new Label("password");

       t_username=new TextField();

       t_userpassword=new TextField();

       b_ok.addActionListener(this);

       b_register.addActionListener(this);

       g_gridlayout=new GridLayout(3,2,10,10);

       this.setLayout(g_gridlayout);

                //this.setBackground(Color.blue);

                add(l_username);

                add(t_username);

       add(l_userpassword);

       add(t_userpassword);

       add(b_ok);

       add(b_register);

    }

    public void actionPerformed(ActionEvent ev)

    {

           String s_label=ev.getActionCommand();

           if (s_label.equals("ok"))

           {

                 t_username.setText("name");

           }

           if (s_label.equals("register"))

           {

                 t_userpassword.setText("password");

           }

    }

    public void paint(Graphics g)

    {

     }

}
分享到:
评论

相关推荐

    editplus 代码编辑器html c++ jsp css

    具体解决方法,在 Editplus 中使用正则表达式,由于“(”、“)”被用做预设表达式(或者可以称作子表达式)的标志,所以查找 “ \n” 时会提示查找不到,所以也就无法进行替换了,这时可以把“(”、“)”使用任意...

    Java开发技术大全 电子版

    9.4使用类标记292 9.5使用关键字instanceof判断所属类292 9.6利用反射获取运行时类信息293 9.6.1使用isInstance()方法判断所属类294 9.6.2获取成员方法信息295 9.6.3获取构造方法信息296 9.6.4获取类的成员...

    Maven权威指南 很精典的学习教程,比ANT更好用

    本例中所用的技术 7.2. simple-parent项目 7.3. simple-model模块 7.4. simple-weather模块 7.5. simple-persist模块 7.6. simple-webapp模块 7.7. 运行这个Web应用 7.8. simple-command模块 7.9. 运行这...

    Java开发技术大全(500个源代码).

    DumpMethods.java 使用反射机制来获取类中的方法 getClassName.java 利用反射机制获取类的名字 invokeConstructor.java 利用反射机制调用构造器 invokeMethod.java 利用反射机制调用成员方法 listConstructors....

    Java语言基础下载

    在Java中使用HQL 709 内容总结 712 独立实践 712 第三十七章 Spring介绍 713 学习目标 713 Spring简介 714 IOC控制反转 714 Spring的容器 715 AOP面向切面编程 715 AOP的专业术语 715 Spring事务管理 718 Spring与...

    22春“计算机科学与技术”专业《web技术》在线作业一答案参考6.docx

    可以通过转义符方式输入字符 C.byte类型的取值范围是0~255 D.bool类型中可以用数字1表示true 参考答案:D 2. Tomcat建立的web应用对文件的大小写是不敏感的。( ) A.正确 B.错误 参考答案:B 3. 若要以加粗宋体、6号...

    freemarker总结

    布尔值:true或false,通常在…&gt;标记中使用 2、 hashes:充当其它对象的容器,每个都关联一个唯一的查询名字 具有一个唯一的查询名字和他包含的每个变量相关联。 3、 sequences:充当其它对象的容器,按次序...

    java 面试题 总结

    动态INCLUDE用jsp:include动作实现 &lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件的...

    网管教程 从入门到精通软件篇.txt

    IV:Open Inventor中使用的文件格式 IVD:超过20/20微观数据维数或变量等级文件 IVP:超过20/20的用户子集配置文件 IVT:超过20/20表或集合数据文件 IVX:超过20/20微数据目录文件 IW:Idlewild屏幕保护程序 ...

    Java学习笔记-个人整理的

    {2.8}框架中移动的小球}{59}{section.2.8} {2.9}抽象与接口}{59}{section.2.9} {2.10}访问控制}{60}{section.2.10} {2.10.1}类的属性}{60}{subsection.2.10.1} {2.10.2}类的方法}{61}{subsection.2.10.2} {...

Global site tag (gtag.js) - Google Analytics