JSP tag 学习
在JSP2.0 中,对于自定义的标签有两种实现方法,实现接口或者继承现有的类
如下图,标注蓝色的是接口,其它是标签类(SimpleTagSupport只在JSP2.0中才有)
在以上接口和类中,定义了一些静态常量,如下:
Tag 中定义:
SKIP_BODY = 0; // 不处理标签体,直接调用doEndTag()方法
EV
SKIP_PAGE = 5; // 不解析标签后面的JSP内容
EV
IterationTag 中定义:
EV
BodyTag 中定义:
EV // deprecated
EV
特别的,对于EV
在doAferBody中返回SKIP_BODY,表示终止标记正文处理;若返回的是 EV,将会再一次调用doAferBody方法,重新处理标记正文,直到返回SKIP_BODY为止。 // ①
TagSupport 默认doStartTag()/doAfterBody()返回SKIP_BODY
BodyTagSupport 默认doStartTag()返回EV
下面是自定义tag的执行过程(由上至下),对于以上各常量的实际运用为:
注意其中的 doInitBody/setBodyContent 方法在自定义标签实现了 BodyTag 接口或继承BodyTagSupport才可以使用
| Tag 方法 | 可返回的静态常量 |
| doStartTag | SKIP_BODY 、EV EV |
|
doInitBody 做标签一些初始化工作,无返回值 setBodyContent 在 doInitBody 之后执行,使用setBodyContent得到JSP页面中标签体之间内容 doAfterBody 最终必须返回SKIP_BODY ,否则可能导致OutOfMemoryError,可参考上面① doEndTag SKIP_PAGE/EV
附 ① 示例代码如下: public int doAfterBody() throws JspException { try { this.pageContext.getOut().write(" } catch (IOException e) { e.printStackTrace(); } if(cou>1){ cou--; return this.EV }else{ return this.SKIP_BODY; // 最终必须返回SKIP_BODY } }
自定义标签的开发包括: 1. 开发标签的处理程序(java类) 2. .tld 文件中指定标签使用的类 3. 在web.xml中指定JSP中使.tld(标签库描述文件)文件的位置。
在.tld文件中 <body-content>JSP <rtexprvalue>false
body-content : 根据web-jsptaglibrary_2_0.xsd(位于servlet-api.jar包($TOMCAT_HOME\common\lib)中的\javax\servlet\resources下,其中web.xml验证时所需要的xsd文件都位于此resources目录下), body-content 的值有下面4种:
tagdependent : 标签体内容 直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释, 如下: select name,age from users
JSP : 接受所有JSP语法,如定制的或内部的tag、scripts、静态HTML、脚本元素、JSP指令和动作。如: <%=request.getProtocol()%> // ②
具体可参考后面附源码。
empty : 空标记,即起始标记和结束标记之间没有内容。 下面几种写法都是有效的,
scriptless : 接受文本、EL和JSP动作。如上述②使用
rtexprvalue: 由请求时表达式来指定属性的值,默认为false,如下必须设置为true:
附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 on // 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(" parseXMLDirective(parent); } else if (reader.matches("<%!")) { parseDeclaration(parent); } else if (reader.matches(" parseXMLDeclaration(parent); } else if (reader.matches("<%=")) { parseExpression(parent); } else if (reader.matches(" parseXMLExpression(parent); } else if (reader.matches("<%")) { parseScriptlet(parent); } else if (reader.matches(" parseXMLScriptlet(parent); } else if (reader.matches(" parseXMLTemplateText(parent); } else if (reader.matches("${")) { parseELExpression(parent); } else if (reader.matches(" 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(" parseXMLDirective(parent); } else if (reader.matches("<%!")) { err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches(" err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches("<%=")) { err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches(" err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches("<%")) { err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches(" err.jspError( reader.mark(), "jsp.error.no.scriptlets" ); } else if (reader.matches(" 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 代替,反之则不可。 “JSP tag 学习 ” 的相关文章在web.xml不认<taglib>解决办法在web.xml不认<taglib>解决办法: 如果是头是这样的<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application&n… <html:select>设置默认值在ActionFrom的reset方法里赋初值就可以,这样不管是调用的action或jsp都会先调用reset方法。… 浏览网页时的错误代号① 客户方错误 100 继续 101 交换协议 ② 成功 200 OK 201 已创建 &nbs… 用java把google和baidu的URL编码还原成明文字串ZT因为在做链接来源统计的时候需要把 http://www.baidu.com/baidu?word= ... B%F7&tn=myie2dg 这类的URL编码还原成明文字串,一般大部分的网站都是用普通的URL编码形式,如上面链接中的badu,这种很容易转换和还原,Java… Struts 防止重复表单提交的工具包今天,我位网友在烦这个东东。他说,怎样防止用户重复提交同一个表单呢?我跟他说用Token。过了一会儿,他说,用Token有点烦。 由于,我的项目里都没有… ServletContext、Session Listener (监听器)ServletContext、Session Listener (监听器) [测试环境:XP_sp2(zh_CN), jdk1.5.0_10(sun), Tomcat 5.0.28] Servlet程序分为三类:· 标准Servlet· 过滤器· 监听器 主要有以下三类:· ServletCon… 发表评论 |