JSP中自定义标记符的使用Word文件下载.docx
《JSP中自定义标记符的使用Word文件下载.docx》由会员分享,可在线阅读,更多相关《JSP中自定义标记符的使用Word文件下载.docx(13页珍藏版)》请在冰点文库上搜索。
%@tagliburi="
/tlds/taglib.tld"
prefix="
tagclass"
%>
html>
<
head>
title>
login<
/title>
/head>
body>
<
tagclass:
loginwidth="
200"
height="
100"
>
/tagclass:
login>
/body>
/html>
在上例中<
就是一个JSP定制标记符。
widtht、height是这个标记的属性。
是一个标记库定义指令,在稍后我们将会讨论。
在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:
TagLibraryDescriptor标记库描述符)文件,标准的XML格式的标记定义文件,被用来存放标记符的信息,下面就是一个典型的TLD文件。
?
xmlversion="
1.0"
encoding="
ISO-8859-1"
?
—XML的版本及其字符集-->
DOCTYPEtaglib
PUBLIC"
-//SunMicrosystems,Inc.//DTDJSPTagLibrary1.1//EN"
"
—文档类型定义-->
taglib>
—此标记说明我们开始描述一个标记库-->
tlibversion>
1.0<
/tlibversion>
—标记库的版本-->
jspversion>
1.1<
/jspversion>
—所使用的JSP的版本-->
shortname>
tagclass<
/shortname>
—缺省的名称-->
tag>
name>
/name>
<
—标记的名称-->
tagclass>
tagclass.login.login
—处理这个Tag的相应的类的名称-->
/tagclass>
info>
<
—对本标记符的描述-->
/info>
attribute>
—开始定义标记的属性-->
height<
<
—属性的名称-->
required>
true<
/required>
—表示这个属性是不是必须的-->
rtexprvalue>
/rtexprvalue>
—表示这个属性是否可以用JSP的程序段的结果输出-->
/attribute>
width<
/tag>
/taglib>
在这个TLD文件中定义了只有一个标记符的标记符库,这个名为login的标记符会调用一个Applet以验证用户的合法性。
处理这个标记的类就是tagclass.login.login。
width、height是这个标记的两个属性。
属性是在使用标记符时作为参数发送的值。
我们可以在上面的示例中增加几个标记,也可以为每个标记添加几个属性。
我们开发标记符库时不一定非要从头开始,自己编写一个全新TLD。
我们可以使用某个集成的开发的环境,也可以修改上面的例子。
TagLib指令
那么当JSP服务器在解析一个标记符时,它是如何定义一个标记库的呢?
这就是TagLib指令的主要责任。
Taglib指令
定义一个标记库以及其自定义标记的前缀.
JSP语法
URIToTagLibrary"
tagPrefix"
例子
描述
%@taglib%>
指令声明此JSP文件使用了自定义的标记,同时引用标记库,
也指定了他们的标记的前缀。
你必须在使用自定义标记之前使用<
指令。
属性
uri="
:
UniformResourceIdentifier(URI)根据标记的前缀对自定义的标记进行唯一的命名,URI可以是一个相对或绝对的路径。
prefix="
:
在自定义标记之前的前缀。
如上例中的<
标记符的处理程序(Taghandle)
我们还是以一个例子来看下如何实现一个Taghandle。
首先是看一下它的类图:
让我们再看一下它的代码:
packagetagclass.login;
importjavax.servlet.jsp.tagext.TagSupport;
importjavax.servlet.jsp.*;
importjava.io.*;
publicclassloginextendsTagSupport
{
publiclogin()
super();
}
publicintdoStartTag()throwsJspTagException
JspWriterout=pageContext.getOut();
try
out.println("
APPLETCODEBASE=applet/login/CODE=login.classwidth=200height=100>
<
/APPLET>
);
catch(Exceptione)
returnSKIP_BODY;
publiccintdoEndTag()throwsJsptagException
returnEVAL_PAGE;
publicvoidrelease()
super.release();
publicvoidsetWidth(Stringlanguage)
this.width=width;
publicStringgetWidth()
returnthis.width;
publicvoidsetHeight(Stringheight)
this.height=height;
publicStringgetHeight()
returnthis.height;
privateStringwidth;
privateStringheight;
从以上我们可以看出,实现一个简单的标记符处理程序有几个要求:
①增加一个类,使之继承java.Servlet.jsp.tagext.TagSupport类。
这个类提供了java.Servlet.jsp.tagext.Tag接口所要求的所有的方法。
另外,还需要使用一些基本的API,使JSP容器能够调用我们自己提供的标记符处理程序。
②必须为每个标记符属性分别创建一个get<
和set<
方法,JSP容器需要使用这些方法处理程序传递参数。
③要为标记符处理程序创建一个构造器和自毁器。
JSP需要使用构造器启动处理程序。
自毁器是在realease()方法中定义的。
在处理程序的生命周期结束时,需要调用自毁器释放所占用的资源。
④创建两个名为doStartTag()和doEndTag()的方法,执行具体的处理和输出动作。
这两个方法是在处理自定义标记符的起始位置和结束位置调用的。
它们的返回值是在TagInterface里定义的静态int,这几个静态值分别是:
SKIP_BODY隐含0:
跳过了开始和结束标签之间的代码。
EVAL_BODY_INCLUDE隐含1:
将body的内容输出到存在的输出流中
SKIP_PAGE隐含5:
忽略剩下的页面。
EVAL_PAGE隐含6:
继续执行下面的页
当然标记符也有它自己的缺点。
很不方便的封装过程,有限的功能。
对于一些不太复杂和功能单一的逻辑描述,需要传递的参数要求不高时,使用JSP标记,要方便的多。
对于大多数的商业逻辑应用,还是使用bean要好的多,也宜于servlet控制。
附录:
文章中所用示例的完整代码
JSP代码:
login.jsp
标记符描述库:
taglib.tld
标记符处理程序:
login.java
标记符处理程序中所使用的Applet:
login.java
importjava.awt.*;
importjava.awt.event.*;
importjava.applet.*;
publicclassloginextendsAppletimplementsActionListener
privateStrings_username;
privateStrings_userpassword;
privateButtonb_ok;
privateButtonb_register;
privateLabell_username;
privateLabell_userpassword;
privateTextFieldt_username;
privateTextFieldt_userpassword;
privateGridLayoutg_gridlayout;
publicvoidinit()
b_ok=newButton("
ok"
b_register=newButton("
register"
l_username=newLabel("
name"
l_userpassword=newLabel("
password"
t_username=newTextField();
t_userpassword=newTextField();
b_ok.addActionListener(this);
b_register.addActionListener(this);
g_gridlayout=newGridLayout(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);
publicvoidactionPerformed(ActionEventev)
Strings_label=ev.getActionCommand();
if(s_label.equals("
))
t_username.setText("
t_userpassword.setText("
publicvoidpaint(Graphicsg)
}