版权所有:(xiaodaoxiaodao)蓝小刀 http://blog.csdn.net/xiaodaoxiaodao/archive/2007/01/05/1474360.aspx
转载请注明来源/作者
在JSP2.0 中,对于自定义的标签有两种实现方法,实现接口或者继承现有的类
如下图,标注蓝色的是接口,其它是标签类(SimpleTagSupport只在JSP2.0中才有)
JspTag (蓝色为接口)
Tag ——〉IterationTag
SimpleTag
BodyTag
TagSupport
BodyTagSupport extends TagSupport implements BodyTag
SimpleTagSupport
在以上接口和类中,定义了一些静态常量,如下:
Tag中定义:
SKIP_BODY = 0; // 不处理标签体,直接调用doEndTag()方法
EVAL_BODY_INCLUDE = 1; // 解析标签体,但绕过doInitBody()和setBodyContent()方法
SKIP_PAGE = 5; // 不解析标签后面的JSP内容
EVAL_PAGE = 6; // 解析标签后,继续解析标签后面的JSP内容
IterationTag中定义:
EVAL_BODY_AGAIN = 2;
BodyTag中定义:
EVAL_BODY_TAG = 2; // deprecated
EVAL_BODY_BUFFERED = 2; //
特别的,对于EVAL_BODY_AGAIN和EVAL_BODY_BUFFERED:
在doAferBody中返回SKIP_BODY,表示终止标记正文处理;若返回的是EVAL_BODY_BUFFERED,将会再一次调用doAferBody方法,重新处理标记正文,直到返回SKIP_BODY为止。 // ①
下面是自定义tag的执行过程(由上至下),对于以上各常量的实际运用为:
注意其中的doInitBody/setBodyContent方法在自定义标签实现了BodyTag接口或继承BodyTagSupport才可以使用
Tag方法
可返回的静态常量
doStartTag
SKIP_BODY、EVAL_BODY_INCLUDE、
EVAL_BODY_AGAIN/EVAL_BODY_BUFFERED
doInitBody
做标签一些初始化工作,无返回值
setBodyContent
在doInitBody之后执行,使用setBodyContent得到JSP页面中标签体之间内容
doAfterBody
最终必须返回SKIP_BODY,否则可能导致OutOfMemoryError,可参考上面①
doEndTag
SKIP_PAGE/EVAL_PAGE
附①示例代码如下:
public int doAfterBody() throws JspException {
try {
this.pageContext.getOut().write("<br>");
} catch (IOException e) {
e.printStackTrace();
}
if(cou>1){
cou--;
return this.EVAL_BODY_AGAIN;
}else{
return this.SKIP_BODY; // 最终必须返回SKIP_BODY
}
}
自定义标签的开发包括:
1. 开发标签的处理程序(java类)
2. .tld文件中指定标签使用的类
3. 在web.xml中指定JSP中使.tld(标签库描述文件)文件的位置。
在.tld文件中
<tag>
<name>out</name>
<tag-class>org.apache.taglibs.standard.tag.el.core.OutTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
body-content:
根据web-jsptaglibrary_2_0.xsd(位于servlet-api.jar包($TOMCAT_HOME\common\lib)中的\javax\servlet\resources下,其中web.xml验证时所需要的xsd文件都位于此resources目录下),body-content的值有下面4种:
<xsd:enumeration value="tagdependent"/>
<xsd:enumeration value="JSP"/>
<xsd:enumeration value="empty"/>
<xsd:enumeration value="scriptless"/>
tagdependent:标签体内容直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释,
如下:
<test:myList>
select name,age from users
</test:myList>
JSP:接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。如:
<my:test>
<%=request.getProtocol()%> // ②
</my:test>
具体可参考后面附源码。
empty:空标记,即起始标记和结束标记之间没有内容。
下面几种写法都是有效的,
<test:mytag />
<test:mytag uname="Tom" />
<test:mytag></test:mytag>
scriptless:接受文本、EL和JSP动作。如上述②使用<body-content> scriptless </body-content>则报错,具体可参考后面附源码。
rtexprvalue:
由请求时表达式来指定属性的值,默认为false,如下必须设置为true:
<test:welcome uname="<%=request.getParameter("username") %>" />
附body-content为JSP/scriptless时标签体可以接受的代码(jasper-compiler.jar包($TOMCAT_HOME\common\lib)中的\org\apache\jasper\compiler\Parser.java中):
JSP:
private void parseElements(Node parent)
throws JasperException
{
if( scriptlessCount > 0 ) {
// vc: ScriptlessBody
// We must follow the ScriptlessBody production if one of
// our parents is ScriptlessBody.
parseElementsScriptless( parent );
return;
}
start = reader.mark();
if (reader.matches("<%--")) {
parseComment(parent);
} else if (reader.matches("<%@")) {
parseDirective(parent);
} else if (reader.matches("<jsp:directive.")) {
parseXMLDirective(parent);
} else if (reader.matches("<%!")) {
parseDeclaration(parent);
} else if (reader.matches("<jsp:declaration")) {
parseXMLDeclaration(parent);
} else if (reader.matches("<%=")) {
parseExpression(parent);
} else if (reader.matches("<jsp:expression")) {
parseXMLExpression(parent);
} else if (reader.matches("<%")) {
parseScriptlet(parent);
} else if (reader.matches("<jsp:scriptlet")) {
parseXMLScriptlet(parent);
} else if (reader.matches("<jsp:text")) {
parseXMLTemplateText(parent);
} else if (reader.matches("${")) {
parseELExpression(parent);
} else if (reader.matches("<jsp:")) {
parseStandardAction(parent);
} else if (!parseCustomTag(parent)) {
checkUnbalancedEndTag();
parseTemplateText(parent);
}
}
Scriptless:
private void parseElementsScriptless(Node parent)
throws JasperException
{
// Keep track of how many scriptless nodes we've encountered
// so we know whether our child nodes are forced scriptless
scriptlessCount++;
start = reader.mark();
if (reader.matches("<%--")) {
parseComment(parent);
} else if (reader.matches("<%@")) {
parseDirective(parent);
} else if (reader.matches("<jsp:directive.")) {
parseXMLDirective(parent);
} else if (reader.matches("<%!")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<jsp:declaration")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<%=")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<jsp:expression")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<%")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<jsp:scriptlet")) {
err.jspError( reader.mark(), "jsp.error.no.scriptlets" );
} else if (reader.matches("<jsp:text")) {
parseXMLTemplateText(parent);
} else if (reader.matches("${")) {
parseELExpression(parent);
} else if (reader.matches("<jsp:")) {
parseStandardAction(parent);
} else if (!parseCustomTag(parent)) {
checkUnbalancedEndTag();
parseTemplateText(parent);
}
scriptlessCount--;
}
由上面可以看出,JSP局限性比较小,在body-content可以使用Scriptless的地方都可以用JSP代替,反之则不可。
注意!!:
EVAL_BODY_BUFFERED 和 EVAL_BODY_INCLUDE 区别是 是否调用 setBodyContent 对BodyContent进行填充~。
分享到:
相关推荐
JSTL教程,jstl技术本身是一个标签库,用来实现jsp页面的显示逻辑。本文档对其核心标签库的使用进行了介绍,可供大家学习使用。
本书的内容面向初学者,以例子为主,在书中提供了JDBC-ODBC翻页例子、MySQL翻页例子、Orion下自定义Tag等等实例帮助学习。
DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <tlibversion>1.2 <jspversion>1.1</jspversion> <shortname>...
基础的jsp costom tag .我们学习用的
display tag 标签 直接导入到myeclipse中就可以学习使用了.
它包括关于JSP Standard Tag Library(JSTL)的详细内容 —— JSTL是一组殷切加入的JSP元素规范,用于多数JSP应用程序中需要的任务。本书开篇阐述了JSP如何充分利用Java servlet来创建高效、可移植的Web应用程序。书...
本书可以满足两类想学习JSP的专业人士的不同需要:一类是网页设计师,他们对如何在网页中使用JSP元素很感兴趣;另一类是程序员,他们对JSP API极为关注,并关心如何在企业级应用程序中有效地使用JSP。如果你是后者,...
15-1 JSP Tag Library 简介 15-2 一个简单的 Tag Library 范例 15-3 Tag Handler Class 15-4 Tag Library 范例程序 第十六章 Simple Tag 与 Tag File 16-1 Simple Tag 16-3 Tag File 16-4 Tag Library Descriptor...
它包括关于JSP Standard Tag Library(JSTL)的详细内容 —— JSTL是一组殷切加入的JSP元素规范,用于多数JSP应用程序中需要的任务。本书开篇阐述了JSP如何充分利用Java servlet来创建高效、可移植的Web应用程序。书...
在网上学习jsp自定义标签的时候, 出现了异常, 在网上寻找了好久, 都没有找到合适的答案, 自己通过摸索最后成功, 分享给大家, 希望能够帮助到你, 自定义标签不能放在java Project中, 只能在java web Project中才可以.
9.3.2 tag 9.4 定位一个tld文件 9.4.1 在Web.xml中定位一个tld文件 9.4.2 直接在JSP文件中定位tld文件 9.5 扩展标签实例 9.5.1 得到父标签的数据 9.5.2 TestTag类 9.5.3 Title类 9.5.4 Data类 9.5.5 TLD...
JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上...
这是一本面向中高级编程人员的自学指导书其重点放在JSP 和其他技术的综合...Tag Library 的详细介绍读者可以把它当作参考手册来使用本作品的第三部分是JDBC 新技术及 其在JSP/Servlet 程序中的应用第九章和第十章...
Jsp+Servlet+JavaBean学习阶段的一个案例总结 名称:留言板(MessageBoard) 开发技术:Jsp+Servlet+JavaBean 数据库:Mysql 开发工具:IntelliJ IDEA 2016.1.3 服务器:Tomcat 8.0.36 功能说明 普通用户:增加删除...
怎样自己定制标签(Custom Tag) (整理的学习笔记) 步骤1、创建一个Tag handler class(标记处理器类) package javax.servlet.jsp.tagext 开发空Body的标签处理器类—–>1)implements Tag 2)extends TagSupport 空Body...
为了使你能够获得最大的进步,建议你再学习的过程中将所有的例子自己进行调试。开始的例子可能会很简单,所以开始的时候你要特别耐心,不要认为太简单而跳过。如果你仔细地调试例子,那么你就会很快地熟悉JSP的本质...
JSP(Java Server Pages)是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag)
一、前言 (本文译自Orion官方站点) 本文将一步一步介绍在Orion Application Server下定义自己的标签,然后,实现该标签的功能,最后用一个jsp例子测试。...3.实现javax.servlet.jsp.tagext.Tag接口:public class H
本版作品是由经验丰富的使用JSP 组建网站的程序员编著内文附有丰富的实例源码供读者学习参 考全书具有语言简明扼要内容丰富范例典型理论与实践相结合的特点不但是从事用JSP 进行网 站开发和设计的初中级读者的自学...
比较完整的jsp Struts2标签。有助于java的学习。