当前位置:首页 > JavaServer Page

JSP tag 学习

canca16年前 (2010-04-08)JavaServer Page533

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("
");

  } 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文件中

    out

    org.apache.taglibs.standard.tag.el.core.OutTag

<body-content>JSP

        value

        true

        <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"/>

    JSP"/>

    empty"/>

    scriptless"/>

 

 

tagdependent 标签体内容 直接被写入BodyContent,由自定义标签类来进行处理,而不被JSP容器解释

如下:

select name,age from users

 

JSP 接受所有JSP语法,如定制的或内部的tagscripts、静态HTML、脚本元素、JSP指令和动作。如:

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

具体可参考后面附源码。

 

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

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

 

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

 

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 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("

            parseXMLDirective(parent);

        } else if (reader.matches("<%!")) {

            parseDeclaration(parent);

        } else if (reader.matches("

            parseXMLDeclaration(parent);

        } else if (reader.matches("<%=")) {

            parseExpression(parent);

        } else if (reader.matches("ession")) {

            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("ession")) {

            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 代替,反之则不可。

扫描二维码推送至手机访问。

版权声明:本文由Ant.Master's Blog发布,如需转载请注明出处。

本文链接:https://iant.work/post/292.html

标签: JavaServer Page
分享给朋友:

“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…

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。