ITPub博客

首页 > 应用开发 > Java > JSP中自定义标记符的使用 (转)

JSP中自定义标记符的使用 (转)

原创 Java 作者:worldblog 时间:2007-12-14 09:37:17 0 删除 编辑
JSP中自定义标记符的使用 (转)[@more@]

JSP中自定义标记符的使用

 

摘要

   在JSP中有一种机制,可以让你在JSP页面中插入与HTML类似的标记。本文介绍JSP定制标记的基本概念和构成,以及如何开发和应用JSP定制标记。XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

 关键字

JSP,XML,TLD,标记符

什么是标记

使用HTML语言我们可以这样去编辑我们的网页:

 

    

</P> <P> HELLO  WORLD</P> <P>

 

 

HELLO WORLD

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

<%@ taglib uri="/tlds/taglib.tld" prefix="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文件。

 

 

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

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

 

 

 

 

  1.0

 

 

 

  1.1

 

 

 

 tagclass

 

 

 

 

     login

    

 

 

tagclass.login.login

 

     

      

 

     

 

      height

       

 

      true

       

 

      true

     

      width

      true

      true

     

 

在这个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" %>

   

  login

   

   

     

 

   

描述

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

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

属性

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

标记符的处理程序(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(" ");

}

     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和set方法,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" %>

 

 

 

 

 

 

 

标记符描述库:taglib.tld

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

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

  1.0

  1.1

 tagclass

 

     login

tagclass.login.login

     

    

      height

      true

      true

     

      width

      true

      true

     

 

标记符处理程序: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(" ");

}

     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)

  {

   }

}


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-993286/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    6241
  • 访问量
    2448551