JSP 1.2 的新功能

来源:互联网 发布:软件绩效考核指标 编辑:程序博客网 时间:2024/06/05 10:16
<script type="text/javascript">google_ad_client = "pub-8800625213955058";/* 336x280, 创建于 07-11-21 */google_ad_slot = "0989131976";google_ad_width = 336;google_ad_height = 280;//</script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>1999年12月,SUN公司发布《JSP 1.1规范》。至今,成千上万的开发者运用此项技术,进行Web动态内容设计。  SUN的众多邮件列表中,《JSP爱好者》拥有4000多订户,位居第二;每天都有新的JSP网站涌现;至今已有约30种JSP图书问世。JSP 1.1 得到绝大多数Web服务器和应用服务器的支持;无数的JSP标签库和框架程序,构成开放式和商业化资源,为开发者提供了便利。   正当世界各地的开发者们为基于JSP 1.1的新应用而忙碌时,负责制定JSP规范的组织JCP(Java Community Process),推出了《JSP 1.2规范》(代号JSR-053)。JCP的成员包括规范作者,应用服务器、JSP和服务器小程序的开发者,他们来自大小小各个公司商家,也有的是开放式资源的参与者。   《JSP 1.2规范》9月17日公布,现已准备广泛实施。JSP 1.2新增若干功能,纠正了低版本的瑕疵。其最重要的变化是: JSP 1.2 建立在 Servlet 2.3 和 Java 2 的基础上;. include 可单独使用,无需设置flush 刷新属性; JSP 页的 XML 语法结构完成定型; 标签(Tag)库可以利用 Servlet 2.3 的事件监听机制; JSP页的有效性验证,增加新方式; 标签库的分发置放,增加若干新选择项式。 标签增加 2 个新接口(interface); String 类型的文本标签,其属性值可以转换成 Object 类型; PropertyEditor 可以转换用户设定的属性值; 标签明确了存续周期; 标签库描述符增设新元素,与 J2EE 的其他描述符合并。   Tomcat 4.0 的实现,参照了 JSP 1.2 和 Servlet 2.3 两个规范。Tomcat服务器是基于 Java 的Web容器,用于运行 Servlet 和 JSP 程序。Tomcat 4.0 与《JSP 1.2规范》已同期发布,您可尝试其各种新鲜功能。有些商品化的Web容器,如新亚特兰大公司的ServletExec 4.1,也已支持JSP 1.2 和 Servlet 2.3。   本文将全面介绍JSP 1.2的新功能及其如何使用。大多数新功能涉及JSP程序员和Web容器开发者,读者应当熟知《JSP 1.1规范》。您若主要关心网页制作,恐怕不会对本文有太多兴趣,但仍可肯定,您会从JSP 1.2获益,譬如:功能更强大的自定义标签库,效率更高的Web容器,以及各种Web容器之间更好的兼容性等等。 Servlet 2.3 和 Java 2   JSP 1.2是根据最新版本《Servlet 2.3规范》制定的。因而,JSP 1.2程序能利小用服务器程序(servlet)的全部新增功能,如经过改进的监听器、过滤器、国际化转换器等。以下,我将说明如何使用标签库中的监听器。怎样利用  Servlet 2.3的其他新增功能,可阅读JavaWorld网站发表的有关Servlet 2.3的文章,作者是杰森·亨特。   JSP 1.2 和 Servlet 2.3 需在JAVA 2平台上运行。令人欣慰的是,一些Web容器,已可利用自JDK 1.1以来新增的全部功能,如收集器、更强的类装载器、灵活的安全机制等,当然,还有您拥有的相应的WEB应用程序。不过,也有美中不足,JSP 1.2应用程序不能运行在仅仅支持JDK 1.1的平台上。好在这样的平台眼下已经寥寥无几,我们中的绝大多数人不必为此烦心。   JSP 1.2向后兼容JSP 1.1。符合《JSP 1.2规范》的Web容器,运行JSP 1.1程序不应遇到不兼容的难题。 Include操作不必设置flush 刷新属性   JSP 1.1强制设置flush刷新属性值为true。因此,当实施include操作时,浏览器中看到的网页内容被刷新,不能再向其转发别的网页,也不能设置"响应"操作的引导信息。由此产生许多混乱和副作用,难以理解和处理。从Sun公司《JSP爱好者》邮件列表文档,可得到关于这个问题的详细说明。   JSP 1.2按照Servlet 2.3的要求,彻底消除这一限制,include命令的flush属性可以设置为false。事实上,flush属性现在是可选择而非强制性的,默认值为false,因而,尽可将其冷落不顾。 JSP 1.1页中像下面的语句,在include操作后执行forward操作,会产生错误。 <% if (someCondition) { %> <% } %> 但是,根据《JSP 1.2规范》,无论将flush的值设为true或false,这些语句都是合法有效的。 甚至,您可以自行定义操作命令标签,将include命令置入其中。 这些语句,因其缓存问题JSP 1.1视为非法,而JSP 1.2认定合法,因为缓存问题已经解决。 JSP页,JSP文档和XML视图   XML是JSP 1.2的重要成员。符合《JSP 1.2规范》的Web容器接受的文件,必须是符合《JSP 1.1规范》的JSP页;或者是遵从XML新格式的JSP文档。   JSP文档有一root元素用作,定义JSP页的标准元素和自定义标签库的格式表(namespace)。JSP的全部命令和标注元素,必须以XML元素表示,取代原先JSP页的旧式元素:
  • ,
  如上例所示,JSP基本元素如说明、自定义操作等,均可包含XHTML之类的XML元素。例中的
  • 即是。   受篇幅所限,本文不能介绍JSP文档的全部语法。注意,JSP文档的语法比JSP页的语法复杂得多,并且,其主要目的是用于各种工具。您若坚持使用这一复杂语法,请阅读《JSP 1.2规范》第5篇"JSP文档"。   Web容器,第一次收到JSP页的请求时,将其转变成类似JSP文档的XML文档,然后检验其是否合法,最后转换为小服务程序。这种XML文档,正规称呼叫做"JSP页的XML视图"。XML视图与JSP文档的唯一区别是:模板化的文本全部包括  在元素中,并以VDATA部件防止文本特殊字符可能带来的问题。例如: ]]> ]]> ]]>   以下还会介绍在XML视图中用TagLibraryValidator检验JSP页的合法性。 标签库分发放置的新方式   JSP 1.2 对标签库分发放置的方式做了一些简化,可以从单独的JAR文件自动查找、分置标签库。 自动查找标签库   JSP 1.1规定,使用标签库时,应当将库操作命令的属性uri设定为标签库所在真实路径,或者指定一个代号名称。如果使用代号名称,必须编辑该项应用的web.xml文件,将此代号名称对应的真实路径,写入元素。   JSP 1.2 给出了可供选用的、功能更强的第三种方法:将标签库JAR文件存放于WEB-INF/lib目录,访问时使用标签库操作命令的标准URI地址。   以下是一例示。标签库描述符(TLD)包括一个元素,定义该库的标准URI地址: ... /demo ...   Web应用程序启动后,Web容器开始搜索WEB-INF目录,查找全部标签库 .tjd文件。标签库 .tjd文件可以单独存在,也可以包含在JAR文件中META-INF目录中。   一个JAR文件中存放多个标签库   自动搜索机制有一大便利,即可以在同一JAR文件中存放多个标签库。   JSP 1.1规定,JAR文件中的标签库描述符TLD必须以META-INF/taglib.tld命名,因此,一个JAR文件只能包含一个TLD,即一个标签库。   JSP 1.2则可以将任何标签库 .tld文件置入JAR文件的META-INF目录内,作为一个TLD。可以把多个TLD和相应的   .class文件,置入同一JAR文件。这就方便了置放标签库。注意,必须使用自动查找机制置放包含多个标签库的JAR文件,因为,对于这种JAR文件无法指定单独TLD路径。0 标签库事件监听   《Servlet 2.3规范》扩展了先前版本的事件监听机制。此前,只能监听会话(session)属性变化,现在则可以监听:小服务程序和会话存续期间的各种事件,小服务程序环境属性的变化,会话开始和暂停事件。会话开始和暂停事件的发生,是由于Web容器将会话状态存于硬盘,或者将会话转至其他服务器。   各种新型事件监听器,源自Java事件模型。监听器是类(class),它实现一个或多个新式监听器接口interface。这些接口定义了响应事件的方法。Web应用程序启动时,Web容器注册它的事件监听器,并适时调用响应事件的方法。   可以将一个或多个事件监听器置入标签库。为了事件监听器能注册,应将实现监听器的类名,写入标签库描述符(TLD)的新元素 com.foo.MyListener   Web容器装载Web应用程序后,会查看全部TLD找出监听器定义,将其注册。   事件监听器可用于多种任务。例如,小服务程序周期监听器,可以在应用程序(如连接池)启动时,为其初始化资源;在其停止运行时,将其关闭。会话周期监听器,可以初始化新会话,或者跟踪会话的数目。   下面是会话周期监听器的示例,它对进行中的会话保持跟踪。 package com.foo; import javax.servlet.*; import javax.servlet.http.*; public class MyListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent hse) { int[] counter = getCounter(hse); counter[0] ; } public void sessionDestroyed(HttpSessionEvent hse) { int[] counter = getCounter(hse); counter[0]--; } private int[] getCounter(HttpSessionEvent hse) { HttpSession session = hse.getSession(); ServletContext context = session.getServletContext(); int[] counter = (int[]) context.getAttribute("com.foo.counter"); if (counter == null) { counter = new int[1]; context.setAttribute("com.foo.counter", counter); } return counter; } }   会话任务数目增加时,小服务程序的环境属性作为计数器,其值增大;会话结束后,半数器值减小。标签可用于简单显示活动会话任务的数目。当活动的或者预定的会话任务达到一定数目,可用标签拒绝建立新会话。 检验器   标签库检验器是JSP 1.2新增重要功能。它的实现,基于类javax.servlet.jsp.tagext.TagLibraryValidator。Web容器   用检验器确定标签库中TLD的信息(强制属性值和空体)是否合法,然后将相应的JSP页转换成小服务程序。应将检验器说明为TagLibraryValidator的子类,并且重设其方法validate(): public ValidationMessage[] validate(String prefix, String uri, PageData pageData)   检验器的validate()方法,由PageData的实例调用。检验器由此获得相应JSP页的XML表达式,即JSP页格式表的  XML视图或者JSP文档(即符合JSP页XML语法的标注)。读完JSP页的XML表达式后,检验器核查TLD信息是否可用,或者核查用户定义的操作元素的信息是否符合类TagExtraInfo的要求。例如,用户定义的A操作必须用作B操作的子元素,检验器可以核查是否使用了B,或者A、B是否以适当的顺序使用。 与检验器相关联的是标签库TLD的新增元素 com.foo.MyValidator 元素指定检验器名称;选择性元素为指定的标签库检验器作配置。 检验器的执行   举例说明。在同一标签库中有操作元素,其中只能用一个作为子元素。下面开始通过各段代码看检验器是是如何工作的: package com.foo; import java.util.*; import javax.servlet.jsp.tagext.*; import org.jdom.*; import org.jdom.input.*; public class MyValidator extends TagLibraryValidator { private SAXBuilder builder = new SAXBuilder(); private Namespace jspNamespace = Namespace.getNamespace("jsp", "http://java.sun.com/JSP/Page");   您已看到,检验器继承了JSP API的TagLibraryValidator。我用JDOM建立这个检验器,处理JSP页的XML表达式。  JDOM包中定义了解析JDOM树的类。当然,您也可以选用其他XML解析器和检验工具,就象标签库项目Jakarta的专家那样,用许多不同的XML工具构建检验器。   我创建了JDOM SAXBuilder类的实例,作为内存变量。如果Web容器中可以存储检验器的实例,我就不必再为各个JSP页逐一创建检验器。我还为JSP的格式表创建了JDOM Namespace的实例变量。下面再对其详细介绍。 检验器必须重设validate()方法: public ValidationMessage[] validate( String prefix, String uri, PageData pd) { ValidationMessage[] vms = null; ArrayList msgs = new ArrayList(); try { Document doc = builder.build(pd.getInputStream()); Element root = doc.getRootElement(); validateElement(root, prefix, msgs); } catch (Exception e) { vms = new ValidationMessage[1]; vms[0] = new ValidationMessage(null, e.getMessage()); } if (msgs.size() != 0) { vms = new ValidationMessage[msgs.size()]; msgs.toArray(vms); } return vms; }   用validator()方法取得JSP页中的XML表达式,用JDOM解析JSP文档。然后,调用validateElement(root, prefix, msgs)方法。root是JSP文档的根本元素,prefix用于标签库,msgs是列表数组用于收集出错信息。如果validateElement()方法发现错误,消息列表便转换成ValidationMessage类型的数组,作为方法调用返回值。   稍后您会看到,ValidationMessage的实例含有出错信息,及其可能出自JSP页原文何处的信息。用数组反映全部JSP页的错误,便于作者集中更改,不必一次又一次的反复纠错。 validateElement()方法,用于调度那些检验指定元素的方法: private void validateElement(Element e, String ns, ArrayList msgs) { if (ns.equals(e.getNamespace().getPrefix())) { if (e.getName().equals("param")) { validateParam(e, ns, msgs); } } if (e.hasChildren()) { List kids = e.getChildren(); Iterator i = kids.iterator(); while(i.hasNext()) { validateElement((Element) i.next(), ns, msgs); } } }   它是递归方法,供JSP文档树中各元素调用。首先,它检查当前的元素是否列在标签库格式表中,然后检查它是否需要检验,如是,则它调用相关方法处理。   本例中,我只检验各种元素的param类型是否合法,但您可以考虑如何扩展该方法,检验其他元素。   包含子结点的各种类型的元素,子结点也分别调用validateElement()方法,于是,它就递归地扫描整个JSP文档树: private void validateParam(Element e, String ns, ArrayList msgs) { Element parent = findParent(e, ns, "redirect"); if (parent == null) { String id = e.getAttributeValue("id", jspNamespace); ValidationMessage vm = new ValidationMessage(id, e.getQualifiedName() " must only be used with 'redirect'"); msgs.add(vm); } }   validateParam()方法调用findParent()方法,检查当前param元素有无redirect类型的父元素。若无,则该param元素用法错误,于是,创建ValidationMessage实例报告出错,并记入错误信息列表。   ValidationMessage包含两条信息:出错信息和相关元素的专用代号。该专用代号由Web容器赋予,并且作为元素标识名称属性,jsp:id,列入JSP格式表,告知检验器。   validateParam()方法发现出错时,首先取得该标识属性,进而将其记入ValidationMessage。此项操作要用到先前提到的Namespace实例变量。   Web容器维护着标识位置对应列表。该列表反映着元素标识与该元素在JSP源文件中的行、列位置的对应关系。借助对应列表生成的出错信息,能指出错误位置,便于查纠。但要注意,Web容器不需要加入此标识。譬如,Tomcat 4.0   不支持这项功能,或许未来版本支持。 最后,findParent()方法的内容如下: private Element findParent(Element e, String ns, String name) { if (e.getName().equals(name) && ns.equals(e.getNamespace().getPrefix())) { return e; } Element parent = e.getParent(); if (parent != null) { return findParent(parent, ns, name); } return null; }   它简单地递归调用,直到发现指定元素,或者递归到JSP文档树顶端。若发现匹配的元素,将其返回,否则,返回mull。   JSP也支持用户扩充新的检验机制,即通过TagExtraInfo类的isValid()方法,检验自己定义专用操作元素。以此方法做出的检验,与上述检验器相比,功能十分有限。既便如此,也比不检验强。 结 论   本文介绍了《JSP 1.2规范》的一些新功能,它们的确会增强您的应用程序。您可以完整利用Java 2 平台和Servlet 2.3 应用程序接口(API)的优势;更加灵活地使用include操作;开发标签库而无需额外配置;以事件监听器简化程序和会话状态管理;创建标签库检验器,全面检验JSP页是否合法,并且得到清晰实用的错误信息。   不过,一切才刚刚开始。本文的第二部分,将详细介绍自定义标签的API,它们是标签开发者喜爱的好工具
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕妇能喝大麦茶 孕妇能喝大麦茶吗 亚历山大麦昆 大麦盒子怎么看电视 大麦茶怎么泡 大麦若叶汁正确喝法 大麦盒子破解网络限制 喝大麦茶有什么好处 大麦虫养殖技术 大麦网抢票攻略 2019大麦网二维码在线查询 喝大麦茶好处 大麦网验证码查询 大麦茶孕妇能喝吗 大麦是燕麦吗 大麦网查询真伪 大麦和小麦区别图片 大麦的功效与作用 大麦米的功效与作用 大麦网网页版 大麦抢票攻略 大麦网怎么抢票 大麦若叶的功效与作用 大麦的作用与功效 大麦若叶粉末价格 炒大麦的功效与作用 大麦面的功效与作用 大麦粉的功效与作用 大麦若叶粉末怎么喝 大麦若叶能减肥吗 大麦荼有什么功效 大麦网演唱会门票 大麦的功效和作用 中演票务通 大麦 大麦票务网站 大麦彩是什么颜色 沈阳演唱会 大麥網 演唱会苏打绿 演唱会门票在哪买 东方票务