1.这个类继承了BodyTagSupport。
2.这个类中我们要实现三个方法,分别是
1)doStartTag(),它有两种返回值分别为
SKIP_BODY:跳过标签体,
EVAL_BODY_INCLUDE:运行标签体。
2)doAfterBody(),它有两种返回值分别为
SKIP_BODY:跳过标签体,
EVAL_BODY_AGAIN:重新调用本方法。
3)doEndTag(),它有两种返回值分别为
EVAL_PAGE:运行结束标签后续内容,
SKIP_PAGE:跳过结束标签后续内容。
现在举一个例子,假设现在有一个类为TestTag,代码如下:
package com.zking.tag.jsptag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class TestTag extends BodyTagSupport {
private int count=0;
/**
* 标签体运行的时候调用的方法
* 返回值:
* 1.SKIP_BODY:跳过标签体
* 2.EVAL_BODY_AGAIN:重新调用本方法
*/
@Override
public int doAfterBody() throws JspException {
System.out.println("我在运行的时候会调用的方法 ");
if(count<3) {
count++;
return EVAL_BODY_AGAIN;
}
else{
return SKIP_BODY;
}
}
/**
* 结束标签运行的时候调用的方法
* 返回值:
* 1.EVAL_PAGE:运行结束标签后续内容
* 2.SKIP_PAGE:跳过结束标签后续内容
*/
@Override
public int doEndTag() throws JspException {
System.out.println("结束标签运行起来了");
return EVAL_PAGE;
}
/**
* 当开始标签运行的时候调用这个方法
* 返回值:
* 1.SKIP_BODY:跳过标签体
* 2.EVAL_BODY_INCLUDE:运行标签体
*/
@Override
public int doStartTag() throws JspException {
System.out.println("开始标签运行起来了");
return EVAL_BODY_INCLUDE;
}
}
它有五个部分组成,分别是
1)tag
2)name:标签名
3)tag-class:该标签的助手类
4) body-content:它可以是空标签,即empty,也可以是jsp,即jsp文档或者表达式
5)attribute:标签属性。
现在举一个例子,假设现在有一个文件名为mytag.tld,我在里面自定义了一个名字叫test的标签,代码如下:
<tag>
<!-- 标签名 -->
<name>test</name>
<!-- 标签助手类 -->
<tag-class>com.zking.tag.jsptag.TestTag</tag-class>
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>jsp</body-content>
</tag>
例如下面的代码:
<%@taglib prefix="z" uri="/zking" %>
首先在mytag.tld里面定义标签和属性,代码如下:
<tag>
<name>forEach</name>
<tag-class>com.zking.tag.jsptag.ForEachTag</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>false</rtexprvalue>
</attribute>
</tag>
然后再到标签助手类即ForEachTag里面定义两个和tld文件属性名一模一样的属性即items和var,并且写上这两个属性的set和get方法,然后再写三个方法,分别是doAfterBody()、doEndTag()、doStartTag()。代码如下:
package com.zking.tag.jsptag;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForEachTag extends BodyTagSupport{
//规则1:tld文件中标签有哪些属性,那么助手类必须要有哪些属性
//规则2:标签助手类中属性名必须跟tld文件属性名一模一样
private List<Object> items;
private String var;
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doAfterBody() throws JspException {
//取出作用域中后续的值
Iterator<Object> it =(Iterator<Object>) pageContext.getAttribute("it");
//判断是否有值
if(it.hasNext()) {
//取值
Object o = it.next();
pageContext.setAttribute(var, o);
pageContext.setAttribute("it", it);
return EVAL_BODY_AGAIN;
}
return SKIP_BODY;
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return EVAL_PAGE;
}
@Override
public int doStartTag() throws JspException {
//只要调用了这个方法,意味着开始标签开始运行了
if(null!=items) {
/**
* 通过迭代器的方式拿到items里面的值开始操作
*/
Iterator<Object> it = items.iterator();
//拿到第一个值
Object o = it.next();
//将这个值以var为键位放入到作用域中
pageContext.setAttribute(var, o);
pageContext.setAttribute("it", it);
return EVAL_BODY_INCLUDE;
}
return SKIP_BODY;
}
}
最后在到自己写的jsp文件里面去循环取值,这里我举个例子,现在有一个jsp页面名字叫admin.jsp,在这里循环输出自己定义的集合里面的值,代码如下:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
List<String> list=new ArrayList();
for(int i=0;i<20;i++){
list.add("zs"+i);
}
session.setAttribute("list", list);
%>
<z:forEach items="${list }" var="a">
${a }<br/>
</z:forEach>
</body>
</html>