`
frank1998819
  • 浏览: 732922 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类

JSP tag 学习 (转)

    博客分类:
  • jsp
 
阅读更多

版权所有:(xiaodaoxiaodao)蓝小刀 xiaodaoxiaodao@gmail.com

http://www.blogjava.net/xiaodaoxiaodao/articles/103438.html

转载请注明来源/作者

JSP2.0 中,对于自定义的标签有两种实现方法,实现接口或者继承现有的类

如下图,标注蓝色的是接口,其它是标签类(SimpleTagSupport只在JSP2.0中才有)

 

 

tag2.JPG

 

 

 

在以上接口和类中,定义了一些静态常量,如下:

 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_AGAINEVAL_BODY_BUFFERED

 

doAferBody中返回SKIP_BODY,表示终止标记正文处理;若返回的是 EVAL_BODY_BUFFERED ,将会再一次调用doAferBody方法,重新处理标记正文,直到返回SKIP_BODY为止。//

 TagSupport 默认doStartTag()/doAfterBody()返回SKIP_BODY

 BodyTagSupport 默认doStartTag()返回EVAL_BODY_BUFFERED / doInitBody()什么也不做 /doAfterBody()返回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语法,如定制的或内部的tagscripts、静态HTML、脚本元素、JSP指令和动作。如:

 

<my:test>

 

<%=request.getProtocol()%>//

 

</my:test>

 

具体可参考后面附源码。

 

 

 

empty 空标记,即起始标记和结束标记之间没有内容。

 

下面几种写法都是有效的,

 

<test:mytag />

 

<test:mytag uname="Tom" />

 

<test:mytag></test:mytag>

 

 

 

scriptless 接受文本、ELJSP动作。如上述使用<body-content> scriptless </body-content>报错,具体可参考后面附源码。

 

 

 

rtexprvalue:

 

由请求时表达式来指定属性的值,默认为false,如下必须设置为true

 

<test:welcome uname="<%=request.getParameter("username") %>" />

 

 

 

 

 

body-contentJSP/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--;

 }

 

由上面可以看出,局限性比较小,在body-content可以使用 Scriptless 的地方都可以用 JSP 代替,反之则不可。

 

===============另一个大师的总结==========================

深入理解BodyTagSupport,包括SKIP_PAGE, EVAL_PAGE等
2009年06月29日 星期一 下午 05:52
 

BodyTagSupport类的方法:
编写标签对应的实现类时,需要重载BodyTagSupport类几个方法:doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag();


他们执行顺序如下:
doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()


doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,
如果返回EVAL_BODY_INCLUDE则继续执行;
如果返回SKIP_BODY则接下来的doInitBody(),setBodyContent(), doAfterBody()三个方法不会被执行,
而直接执行doEndTag()方法。

setBodyContent()方法用于设置标签体内容,如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。
标签体内容执行完后,会调用doAfterBody()方法,此方法可返回EVAL_BODY_TAG, SKIP_BODY,
EVAL_PAGESKIP_PAGE
如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;
如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;
如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。

 

标签中静态常量:

EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
SKIP_BODY:告诉服务器不要处理正文内容
EVAL_PAGE:让服务器继续执行页面
SKIP_PAGE:让服务器不要处理剩余的页面
EVAL_BODY_AGAIN:让服务器继续处理正文内容,只有doAfterBody方法可以返回
EVAL_BODY_BUFFERED:BodyTag接口的字段,在doStartTag()返回
EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回。

 

 

 

分享到:
评论

相关推荐

    JSP Standard Tag Library——JSTL

    JSTL教程,jstl技术本身是一个标签库,用来实现jsp页面的显示逻辑。本文档对其核心标签库的使用进行了介绍,可供大家学习使用。

    JAVA_JSP学习系列

    本书的内容面向初学者,以例子为主,在书中提供了JDBC-ODBC翻页例子、MySQL翻页例子、Orion下自定义Tag等等实例帮助学习。

    学习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"&gt; &lt;tlibversion&gt;1.2 &lt;jspversion&gt;1.1&lt;/jspversion&gt; &lt;shortname&gt;...

    jsp costom tag

    基础的jsp costom tag .我们学习用的

    JSP标签display tag实例

    display tag 标签 直接导入到myeclipse中就可以学习使用了.

    JSP设计第二版(附源码).rar

    它包括关于JSP Standard Tag Library(JSTL)的详细内容 —— JSTL是一组殷切加入的JSP元素规范,用于多数JSP应用程序中需要的任务。本书开篇阐述了JSP如何充分利用Java servlet来创建高效、可移植的Web应用程序。书...

    JSP设计第二版 - 内附源码(PDF中文版)

    本书可以满足两类想学习JSP的专业人士的不同需要:一类是网页设计师,他们对如何在网页中使用JSP元素很感兴趣;另一类是程序员,他们对JSP API极为关注,并关心如何在企业级应用程序中有效地使用JSP。如果你是后者,...

    JSP2.0技术手册pdf(带示例源码).zip

    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 servlet 入门学习资料-新手一看就懂

    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设计第二版(附源码)

    它包括关于JSP Standard Tag Library(JSTL)的详细内容 —— JSTL是一组殷切加入的JSP元素规范,用于多数JSP应用程序中需要的任务。本书开篇阐述了JSP如何充分利用Java servlet来创建高效、可移植的Web应用程序。书...

    jsp自定义标签报错的问题

    在网上学习jsp自定义标签的时候, 出现了异常, 在网上寻找了好久, 都没有找到合适的答案, 自己通过摸索最后成功, 分享给大家, 希望能够帮助到你, 自定义标签不能放在java Project中, 只能在java web Project中才可以.

    JSP语法基础(jsp入门)

    JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上...

    jsp+j2ee

    这是一本面向中高级编程人员的自学指导书其重点放在JSP 和其他技术的综合...Tag Library 的详细介绍读者可以把它当作参考手册来使用本作品的第三部分是JDBC 新技术及 其在JSP/Servlet 程序中的应用第九章和第十章...

    java-jsp留言板

    Jsp+Servlet+JavaBean学习阶段的一个案例总结 名称:留言板(MessageBoard) 开发技术:Jsp+Servlet+JavaBean 数据库:Mysql 开发工具:IntelliJ IDEA 2016.1.3 服务器:Tomcat 8.0.36 功能说明 普通用户:增加删除...

    jsp 定制标签(Custom Tag)

    怎样自己定制标签(Custom Tag) (整理的学习笔记) 步骤1、创建一个Tag handler class(标记处理器类) package javax.servlet.jsp.tagext 开发空Body的标签处理器类—–&gt;1)implements Tag 2)extends TagSupport 空Body...

    JSP由浅入深-JSP由浅入深

    为了使你能够获得最大的进步,建议你再学习的过程中将所有的例子自己进行调试。开始的例子可能会很简单,所以开始的时候你要特别耐心,不要认为太简单而跳过。如果你仔细地调试例子,那么你就会很快地熟悉JSP的本质...

    JSP学习笔记

    JSP(Java Server Pages)是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag)

    JAVA/JSP学习系列之七(Orion下自定义Tag)

    一、前言 (本文译自Orion官方站点) 本文将一步一步介绍在Orion Application Server下定义自己的标签,然后,实现该标签的功能,最后用一个jsp例子测试。...3.实现javax.servlet.jsp.tagext.Tag接口:public class H

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    此外,本书的配套光盘还免费提供了价值人民币330元的java教学视频,对java语言进行了全面讲解,帮助一些不会java语言的读者快速地从java基础知识的学习中过渡到java web的学习与开发上. 第1部分 xml篇. 第1章 xml...

    Jsp struts2标签大全

    比较完整的jsp Struts2标签。有助于java的学习。

Global site tag (gtag.js) - Google Analytics