您的位置:首页 > Web前端 > JavaScript

黑马总结: jstl自定义标签

2011-03-21 23:47 281 查看
创建一个自定以标签,需要时java类,一个tld文件。这些准备工作,和自定义个el函数一样。但是这里有一点小的区别就是java的方法不是static的了。el函数是一个java类。不继承和实现任何一个类和接口。但是自定义标签需要实现一个tag接口。实现起来比较复杂。所以,我们只要继承TagSupport或者BodyTagSupport其中的一个。看字面的上的意思,就可以明白一个类是不带有标签体的标签一个带有标签体的标签的。

首相我们要谈谈不带标签体的标签的生命周期。首相就是new一个标签的时候,标签会首相调用setPage、setParent、setter等方法。着是在给标签内部的变量赋值的一个过程。然后标签会调用doStartTag和doEndTag方法。当然根据放回值的不同,返回值的不同,可能会重复执行方法或者直接结束调用。下面的代码

package org.skycn.calculator;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

public class Mytag extends TagSupport {
/**
* 这是是你标签中的属性,同时你必须生成set方法。
*/
private String name;

public void setName(String name) {
this.name = name;
}

/***
* 为什么我覆盖这样的方法?不是别的方法,返回值有是什么?
* 首先看看,这个不带有标签体的方法的生命周期。
*/
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
/**
* 这个标签只是为你把值保存在page作用域里面
*/
this.pageContext.setAttribute("name", this.name );

return super.doEndTag();
}

}


<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1">

<tlib-version>1.1</tlib-version>
<short-name>MyTag</short-name>
<uri>http://www.skycn.com/MyTag</uri>

<tag>
<name>catch</name>
<tag-class>org.skycn.calculator.Mytag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>


下面是如何下一个自定义的带标签体的标签,我们来重写for循环标签。

首先还是生命周期的问题。我们要知道,我们的标签是有标签体的,里面可能还要嵌套其他标签库的标签。在实际开发中,很多的标签是要嵌套使用的。这样才能让我们复杂的程序,运行在美观的jsp页面上。让程序员和美工都可能看的一目了然了。

首先,在创建对象的时候, 标签会首相调用setPage、setParent、setter等方法。但后是doStartTag、serBodyContext,doInitBody、然后是计算Body里面的内容。也就是赋值的过程。然后是doAfterBody,这个方法有俩个返回值,直接控制是否重复调用。

EVAL_BODY_AGAIN 重复调用doAfterBody方法。 SKIP_BODY结束调用。这里面需要强调一返回值,就是doStratTag方法中的EVAL_BODY_INCLUDE。这个返回,不仅仅可以继续执行下面的方法,还可以把,定义的标签属性,写到输出流中。方便我们输出。这个是自动的。代码实现如下

package org.skycn.calculator;

import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class MyTagFor extends BodyTagSupport {
/**
* 这个里面定一个集合,我们不考虑数组的这个情况。
*/
private Collection items;
private String var;
private Iterator it;

public void setItems(Collection items) {
this.items = items;
}
public void setVar(String var) {
this.var = var;
}
/**
* 根据声明周期,我们知道,如果items为null或者说长度为0,我们就没有必要再继续这个标签体的方法了。所以,我们就可以在doStartTag方法中
* 直接跳出。
*/

@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub

if(it.hasNext())
{
this.pageContext.setAttribute(var,it.next());
return EVAL_BODY_AGAIN;// 这个返回值,是让方法继续循环执行方法
}
return SKIP_BODY;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub

if( items == null || items.size() == 0)
{
return SKIP_BODY;//这个返回值在doStartTag方法和doAfterBody方法中可以起到直接结束当前方法的作用
}
it = items.iterator();
return EVAL_BODY_INCLUDE;//这个返回值,可以让我们的数据自然的保存在输出流中。并且继续下面的方法,这个返回值我们要特别的注意
}

}


<tag>
<name>for</name>
<tag-class>org.skycn.calculator.MyTagFor</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: