1.编写助手类
package com.zking.tagdemo.tag;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForeachTag extends BodyTagSupport{
//存放数据源
private List<?> items;
private String var;
public List<?> getItems() {
return items;
}
public void setItems(List<?> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doStartTag() {
//判读数据源是否为空
//Objects.isNull--一个工具类判断是否为空
if(Objects.isNull(this.items) || this.items.size() == 0) {
return SKIP_BODY;//如果是就跳出标签体
}
//如果不是空首先获取到一个迭代器
Iterator<?> iterator = this.items.iterator();
//获取到第一个对象
Object obj = iterator.next();
this.pageContext.setAttribute(var, obj);
//把迭代器直接放到页面的作用域中去
this.pageContext.setAttribute("iterator", iterator);
return EVAL_BODY_INCLUDE;//返回EVAL_BODY_INCLUDE(标志值)就会自动调用doAfterBody()
}
@Override
public int doAfterBody() {
//从pageContext(上下文)中获取迭代器
Iterator<?> it =(Iterator<?>)this.pageContext.getAttribute("iterator");
//判断有没有下一个值
if(it.hasNext()) {
//如果有就取出来一个放到页面做用域
this.pageContext.setAttribute(this.var, it.next());
return EVAL_BODY_AGAIN;//
//因为return返回了,直接退出了询环体所以用if
}
return SKIP_BODY;
}
}
2.编写tld文件(必须放在WEB-INF目录或其目录下)
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>Simple Tags</short-name>
<uri>/zking</uri>
<tag>
<!-- 标签名 -->
<name>out</name>
<!-- 标签助手类 -->
<tag-class>com.zking.tagdemo.tag.OutTag</tag-class>
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>empty</body-content>
<attribute>
<!-- 属性名, OutTag类中的val属性相匹配 -->
<name>val</name>
<!-- 表示该属性为必要的属性 -->
<required>true</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>true</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签val属性,用于输出val的值</description>
</attribute>
<attribute>
<!-- 属性名, OutTag类中的defaultVal属性相匹配 -->
<name>defaultVal</name>
<!-- 表示该属性为必要的属性 -->
<required>false</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>false</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签,如val属性值为空,则输出该默认值</description>
</attribute>
</tag>
<!--if标签的定义 -->
<tag>
<name>if</name>
<tag-class>com.zking.tagdemo.tag.ifTag</tag-class>
<!--该标签有标签体-->
<body-content>jsp</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!--foreach标签的定义 -->
<tag>
<name>foreach</name>
<tag-class>com.zking.tagdemo.tag.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>
</taglib>
3.测试数据辅助类
package com.zking.tagdemo.tag;
public class Book {
private int id ;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book [id=" + id + ", name=" + name + "]";
}
}
public class TestData {
public static List<Book> getBooks() {
List<Book> books = new ArrayList<>();
Book b1 = new Book();
b1.setId(1);
b1.setName("水浒传");
Book b2 = new Book();
b2.setId(2);
b2.setName("红楼梦");
Book b3 = new Book();
b3.setId(3);
b3.setName("西游记");
books.add(b1);
books.add(b2);
books.add(b3);
return books;
}
}
4 在页面上使用标签
<%@page import="com.zking.tagdemo.tag.TestData"%>
<%@page import="com.zking.tagdemo.tag.Book"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
//获取测试数据
List<Book> books = TestData.getBooks();
//放入request对象中
request.setAttribute("books", books);
%>
<z:foreach items="${books}" var="book">
<p>${book.id } - ${book.name }</p>
</z:foreach>
</body>
</html>
5运行结果