2. Taglib技术:
Taglib作为jsp之上的辅助技术,其工作本质依托与jsp技术,也是自定义标签翻译成java代码,不过这次和jsp略有不同,它还要经过几个过程。
先来看一下,实现一个tag的2个要点:
1. 提供属性的set方法,此后这个属性就可以在jsp页面设置。以jstl标签为例 c:out value=""/,这个value就是jsp数据到tag之间的入口。所以tag里面必须有一个setValue方法,具体的属性可以不叫value。例如setValue(String data){this.data = data;}。这个“value”的名称是在tld里定义的。取什么名字都可以,只需tag里提供相应的set方法即可。
2. 处理 doStartTag 或 doEndTag 。这两个方法是 TagSupport提供的。还是以c:out value=""/为例,当jsp解析这个标签的时候,在“<”处触发 doStartTag 事件,在“>”时触发 doEndTag 事件。通常在 doStartTag 里进行逻辑操作,在 doEndTag 里控制输出。
在处理tag的时候:
0. 从tagPool中取得对应tag。
1. 为该tag设置页面上下文。
2. 为该tag设置其父tag,如果没有就为null。
3. 调用setter方法传入标签属性值tag,如果该标签没有属性,此步跳过。
4. 调用doStartTag方法,取的返回值。
5. 如果该标签有body,根据doStartTag返回值确定是否pop该标签内容。如果要pop其body,则:setBodyContent(),在之后,doInitBody()。如果该标签没有body,此步跳过。
6. 调用doEndTag()以确定是否跳过页面剩下部分。
7. 最后把tag类返还给tagPool。
|
tag类为: package my.customtags; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; public class Hidden extends TagSupport{ String name; public Hidden(){ name = ""; } public void setName(String name){ this.name = name; } public void release(){ value = null; } public int doStartTag(){ return EVAL_BODY_INCLUDE;} public int doEndTag() throws JspTagException{ try{ pageContext.getOut().write(", you are welcome"); } catch(IOException ex){ throw new JspTagException("Error!"); } return EVAL_PAGE; } } Jsp页面: <my:hidden name="testname"/> 生成的jsp代码: my.customtags.Hidden _jspx_th_my_hidden_11 = (my.customtags.Hidden) _jspx_tagPool_my_hidden_name.get(my.customtags.Hidden.class); _jspx_th_my_hidden_11.setPageContext(pageContext); _jspx_th_my_hidden_11.setParent(null); _jspx_th_my_hidden_11.setName("testname"); int _jspx_eval_my_hidden_11 = _jspx_th_my_hidden_11.doStartTag(); if (_jspx_th_my_hidden_11.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) return true; _jspx_tagPool_my_hidden_name.reuse(_jspx_th_my_hidden_11); return false; |
Taglib技术提供两个机制,Body和non-Body导致了taglib的出现了两个分支:Display Tag和Control Tag, 前者在java code中嵌入了html标签,相当与一个web component,而后者则是另一种模板脚本。
四、两种技术方案的比较:
1. 技术学习难易度
模板技术。使用模板技术,第一点就是必须学习模板语言,尤其是强控制的模板语言。于是模板语言本身的友好性变的尤为重要。以下依据友好性,表现力以及复用性三点为主基点比较了一下几种模板技术。
|
Velocity: Turbine项目(http://jakarta.apache.org/Turbine)采用了velocity技术。 1. 友好性不够。理由: 强控制类型,出现页面显示控制代码和html混合。与Html的不兼容,无法所见即所得。遇到大的HTML页面,从一个 “#if”找到对应的 “#end”也是很痛苦的一件事情。 2. 表现力强。理由:强控制语言。 3. 复用性弱。理由:模板脚本和页面代码混合。 |
|
XSLT Cocoon项目(http://cocoon.apache.org/)采用XML + XSLT的方法。CSDN社区也是采用此方案。 1. 内容和显示风格分离,这点XSLT做的最好。 2. 速度慢。理由:XSLT的使用XPath,由于是要解析DOM树,当XML文件大时,速度很慢。 3. 友好性不够。理由:由于没有HTML文件,根本看不到页面结构、显示风格和内容。XSL语法比较难以掌握,由于没有“所见即所得”编辑工具,学习成本高。 4. 表现力强。理由:强控制语言。 5. 复用性弱。理由:xsl标签和html标签混合。 |
|
JDynamiTe 1. 表现力中等。理由:弱控制语言。 2. 友好性强。理由:所见即所得的效果。在模板件中的ignore block在编辑条件下可展示页面效果,而在运行中不会被输出。 3. 复用性强。理由:利用html标签。 |
|
Tapestry 1. 友好性中等。理由:整个Tapestry页面文件都是HTML元素。但是由于component会重写html标签,其显示的样子是否正确,将不预测。 2. 表现力强。理由:强控制语言。 3. 复用性强。理由:扩展了HTML元素的定义。 |
在JSP中大量的使用TagLib,能够使得JSP的页面结构良好,更符合XML格式,而且能够重用一些页面元素。但TagLib的编译之后的代码庞大而杂乱。TabLib很不灵活,能完成的事情很有限。TabLib代码本身的可重用性受到TagSupport定义的限制,不是很好。 另外是,我不得不承认的一件事是,TagLib的编写本身不是一件愉快的事情,事实我个人很反对这种开发方式。
2. 技术使用难易度
模板技术:模板技术本身脱离了Web环境,可以在不启动Web server得情况下进行开发和测试,一旦出错详细的信息易于错误的定位。由于模板引擎的控制,页面中将只处理显示逻辑(尽管其可能很复杂)
JSP技术:工作在Web环境下,开发测试一定要运行web server。此外,一些TagLib能够产生新的标签,页面的最终布局也必须在web环境下才可以确定。测试时出错信息不明确,特别是TagLib得存在,极不容易定位。由于其本质是程序,很容易在其中写入业务逻辑,甚至于数据库连接代码,造成解耦的不彻底。
3. 总结
模板技术更加专注于页面的显示逻辑,有效帮助开发人员分离视图和控制器。在学习,开发和测试都更加容易。
更多内容请看PCdog.com--jsp文摘专题
