加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 教程 > 正文

JSP中自定义标记符的引用

发布时间:2023-05-19 15:20:55 所属栏目:教程 来源:
导读:摘要
   在jsp中有一种机制,可以让你在jsp页面中插入与html类似的标记。本文介绍jsp定制标记的基本概念和构成,以及如何开发和应用jsp定制标记。

关键字
jsp,xml,tld,标记符

什么是标记
使用html语
摘要
   在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)
 
    {
 
     }
 
}
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!