自定义标签

1,任何一个标签都对应一个java类,该类必须实现Tag接口或者TagSupport接口。JSP遇到一个标签后通过一个tld文件查找到标签的实现类。并运行该类相应的方法。

2,自定义标签方法的调用

public interface Tag{

public final static int SKIP_BODY=0;

public final static int EVAL_BODY_INCLUDE=1;

public final static int SKIP_PAGE=5;

public fianl static int Eval_PAGE=6;

void setPageContext(PageContext pageContext);

void setParent(Tag parent);

Tag getParent();

int doStartTag()throws JspException;

int doEndTag()throws JspException;

void release();

}

所有Tag接口的方法都会在执行标签的时候被JSP页面调用。通过调用setPageContext方法注释JSP的pageContext对象,通过调用setParet注释标签的父标签。doStartTag与doEndTag分别在进入标签与退出标签的时候被执行。

 

doStartTag和doEndTag的返回值会影响到程序的流程。

方法执行顺序:

setPageContext()--》seltParent-->

(1)doStartTag-->(返回值为Eval_BODY_INCLUDE执行标签体内部的代码)

(2)doStartTag-->(返回值为SKIP_BODY跳过标签体)

 

---》endStartTag()-->

(1)(返回值为skip_page标签执行完毕,也不会继续执行标签后面的代码)

(2)(返回值为Eval_Page标签执行完毕,继续执行标签后面的代码)

relaase()方法在关闭web应用的时候被容器调用。

 

3,TagSupport类

多数情况下不需要直接实现Tag接口,使用TagSupport类就可以了,TagSupport是java提供的一个模板类,实现了PageCotext与parent的getter和Setter方法以及其他一些功能。需要做的只是根据需要实现doStartTag()方法与DoEndTag()方法。

 

4,带参数的标签

标签的参数是通过Tag实现类的setter方法注释进去的,因此,定义带参数的标签只需要给类加上一个属性以及对应的setter方法就可以了

同时在tld文件中指明该参数:

<attribute>

<name>name</name>

<required>true</required>

<rtexprvalue>true</rtexprvalue>

</attribute><name>表明该属性的名称,<required>表明该属性是否是必须得。

<rtexprvalue>表明是否允许EL表达式或者Scriptlet"<%=%>"

5,带多个参数的标签

定义多个参数的标签只需要在类实现里定义多个setter方法,并在taglib里声明多个参数就可以了

6,带标签体的自定义标签

实现BodyTag接口。BodyTag是Tag接口的子类,专门处理带标签体的标签。

BodyTag接口除了具有Tag接口的doStartTag(),doEndTag()等方法外,还具有其他方法

BodyTag中方法执行流程

 void setPageContext()-->voidsetParent()-->int doStartTag()-->

(1)返回值为eval_body_buffered 或者eval_body_tag

-->void setBodycontent()-->void doInitBody()-->int doAfterBody();

(2)如果为eval_body_include-->int doAfterBody();

(3) 如果为skip_body-->doEndTag();

int do AfterBody

(1)返回值为seval_body_agin-->int doAfterBody();

(2)返回值为skip_body-->int doEndTag();

 

 

doStartTag()方法的返回值如果为Eval_body_include,则会直接输出标签体内容;如果为Eval_body_buffered,则不会输出,而是将标签体内容通过setBodyContent()方法注释到标签类里,然后就可以使用getBodycontent()方法得到标签体的内容。

只要是在setBodyContent方法之后调用的方法都可以使用getBodyContent()方法。

7,多次执行循环标签体

可以设置一个属性来设置循环的次数。

doAfterBody()方法内输出是写入到bodyContent缓存中的,因此每次通过getBodyContent()取出的值都会递增的。

8,带动态属性的自定义标签

自定义标签支持动态属性。只要实现了DynamicAttributes接口,并实现该接口的setBynamicAttribute方法,该标签就可以使用动态属性。

同时,tld文件中需要定义该标签为可带冬天属性的标签。

<tag>

<dynamic-attributes>true</dynamic-attributes>

</tag>

9,嵌套的自定义标签

有时候需要多个标签联合起来实现一个功能,这些标签彼此嵌套。其中,最里面的标签可以通过getParent()方法获取到上层标签,再通过一些getter、setter方法等就能够访问到上层标签的内容。标签的parent属性是由JSP在运行时注入进去的。通过getParent()方法来获取父标签,这就是嵌套标签的工作原理。嵌套标签有时候也称为组合标签。

 10,JSP2.x标签

JSP1.x的自定义标签使用起来还是非常复杂的。从JSP2.0开始,JSP提供了一套简化的标签。JSP2.x标签没有那么多的方法与返回值。

 

SimpleTag接口

SimpleTag接口只有一个void doTag()方法,同时支持参数与标签体。使用时一般直接集成SimpleTagSupport类。

tld文件的配置和JSP1.x标签完全一样。

对于一般的应用,SimpleTag十分简单。所有的工作均在没有返回值的doTag()方法里完成。实际上,如果使用JSP1.x的标签,尽管有那么多的方法与返回值,多数情况下也只需要TagSupport类的doEndTag()方法就行了,默认的流程会满足要求。

 

 

带标签体的JSP2.x标签

SimpleTag也可以带有标签体。SimpleTag的标签体处理方法与JSP1.x的标签完全不同。1.x的标签体公国setBodyContent()方法注入到BodyTag中,通过getBodyContent()即可以得到标签体。而SimpleTag是通过一种叫做jspFragment的对象实现的,标签体的内容被封装为JSPFragment对象,通过getJspBody()方法可以得到该对象,getJspContext().getOut(),jspFragment.invoke(writer)通过invoke方法将方法体的内容输出到指定的Write中,如果直接输出可以使用jspFragment.invoke(null),该标签的tld配置与jsp1.x标签基本一致,注意这里的bodyContent是tagdependent而不能是JSP与empty。

 

带多个标签体的JSP2.x标签

与JSP1.x不同,2.x标签可以有多个标签体,并且可以按照不同顺序,不同的次数分别调用标签体。多个标签体需要借助于JSP的<JSP:attribut/>行为。

jsp页面

<tablib:multiAttribute>

<jsp:attribute name="body1">标签体一,</jsp:attribute>

<jsp:attribute name="body1">标签体二,</jsp:attribute>

</tablib:multiAttribute>

多个标签体使用<jsp:attribute/>行为分开。JSP2.x标签可以获取到多个标签体,并可以以任何顺序,任意次数地调用他们。

这两个标签体实际上是类的两个属性,不同的是,这两个属性必须是JspFragment类型的,也必须通过<jsp:attribute/>行为设定。而且tld配置文件必须配置为fragment类型

<attribute>

<name>body</name>

<required>false</required>

<fragment>true</fragment>

</attribute>

11,编写自定义方法

JSTL提供了一些最基本的方法,封装在function下,如${fn:length}d等。标签的方法也是可以自由扩展的。如果现有的方法库没有满足需要,就可以使用自定义方法来扩展它。

自定义方法

标签的自定义方法实际上是一些类的静态方法。自定义方法不需要集成人和类或者实现任何接口。

方法描述文件

自定义方法需要在tld文件中定义。在/web-inf文件夹下新建文件function.tld输入如下内容。

<function>

<description></description>

<name>length</name>

<function-class>com.function.Function</function-class>

<function-signature>

int length(java.lang.Object,int)

</function-signature>

<example>

${fn:length(string)}

</example>

自定义方法的声明卸载<function-signature>标记里,格式为"返回值方法名(参数一类型,参数二类型)"

如果tld文件没有位于/web-inf下面,可以在web.xml中导入该文件。方法同自定义标签是一样的。

<jsp-config>

<taglib>

<taglib-uri>http://www.helloweenvsfei.com/function</taglib-uri>

<taglib-location>/web-inf/function.tld</taglib-location>

</taglib>

</jsp-config>

或者直接在jsp中使用相对路径引入该文件:

<%@ taglib uri="/web-inf/function.tld" prefix="fn"%>

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/zrfmmhy/p/3497159.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值