Iterate.java
package customTag;
import java.util.Collection;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
/**
* 迭代
* @author hzc
*
*/
public class Iterate extends TagSupport{
private Object items;
private String var;
private Iterator it;
public Object getItems() {
return items;
}
public void setItems(Object items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doAfterBody() throws JspException {
if(it.hasNext()) {
//把遍历到的元素用var属性值作为名存放到pageContext中
this.pageContext.setAttribute(var, it.next());
return EVAL_BODY_AGAIN;//要求容器重复执行标签主体内容
}else {
return SKIP_BODY;
}
}
@Override
public int doStartTag() throws JspException {
if(items == null || !(items instanceof Collection)) {
return SKIP_BODY;
}
it = ((Collection)items).iterator();//获取结合迭代器
if(it.hasNext()) {
//把遍历到的以第一元素用var属性值作为名存放到pageContext中
this.pageContext.setAttribute(var, it.next());
return EVAL_BODY_INCLUDE;//要求容器执行标签体内容
}else {
return SKIP_BODY;//如果集合中没有元素就跳过标签体
}
}
}
TagDemo2.java(小写转大写)
package customTag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* 把主体返回的内容转换成大写的自定义标签使用示例
* 为什么要用BodyTagSupport实例的getPreviousOut()方法来获取JspWriter实例,而不是直接从BodyContent实例中调用getEnclosingWriter()来获取?
* 这是因为自定义标签有可能会嵌套到其他标签中使用,这时每个标签都会有自己的BodyContent实例,每个内层标签处理类要通过getPreviousOut方法来获取上一层标签处理类的输出对象,这样每个标签的返回内容才能最终通过顶层输出对象写到响应中。
* @author hzc
*
*/
public class TagDemo2 extends BodyTagSupport{
private int count = 1; //要循环的次数,默认为1
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public int doAfterBody() throws JspException {
if(count > 0) {
//以文本的方式获取标签主体的内容
String bodyString = getBodyContent().getString();
try {
if(bodyString != null) {
//获取外层标签的输出流对象
JspWriter out = getPreviousOut();
out.print(bodyString.toUpperCase());
}
bodyContent.clearBody(); //清楚缓存的标签主体内容
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count--;
return EVAL_BODY_AGAIN; //继续执行标签主体内容
}else {
count = 1;
return SKIP_BODY;
}
}
}
MySimpleTag.java
package customTag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MySimpleTag extends SimpleTagSupport{
private int count = 1;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public void doTag() throws JspException, IOException {
//获取页面输出流
JspWriter out = this.getJspContext().getOut();
String str = invokeBody();
for(int i = 0;i<count;i++) {
out.println(str.toUpperCase());
}
}
// 获取标签主体返回内容
protected String invokeBody() throws JspException{
//获取代表该标签主体的JspFragment实例
JspFragment body = getJspBody();
StringWriter sw = new StringWriter();
try {
if(body != null) {
//执行标签主体片段,把返回的内容写到字符流中
//若只想输出标签主体的生成内容,可以使用null参数调用invoke()方法
body.invoke(sw);
}
} catch (JspException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sw.toString(); //以字符串的形式返回该缓冲区的当前值
}
}
iterate.tld
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
<tlib-version>tlib-version</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>short-name</short-name>
<uri>http://www.hzc.com/tag/iterate</uri>
<tag>
<name>iterate</name>
<tag-class>customTag.Iterate</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<!-- 此属性是必要的 -->
<required>true</required>
<!-- 属性值可以在JSP运行时期动态产生 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>toUpperCase</name>
<tag-class>customTag.TagDemo2</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>count</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>SimpleUpperCase</name>
<tag-class>customTag.MySimpleTag</tag-class>
<!-- 主体内容只能是empty、scriptless、tagdeoedent之一 -->
<body-content>scriptless</body-content>
<attribute>
<name>count</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>jspdemo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<taglib>
<taglib-uri>http://www.hzc.com/tag/iterate</taglib-uri>
<taglib-location>/WEB-INF/tlds/iterate.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://www.hzc.com/ELFunction</taglib-uri>
<taglib-location>/WEB-INF/tlds/ELFunction.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>
iterate.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://www.hzc.com/tag/iterate" %>
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
List<String> list = new ArrayList<String>();
list.add("hzc");
list.add("zzl");
pageContext.setAttribute("list", list);
%>
<h2>迭代</h2>
<c:iterate items="${list }" var="item">${item }<br></c:iterate>
<c:toUpperCase count="3">hzc<br></c:toUpperCase>
<c:SimpleUpperCase count="4">zzl<br></c:SimpleUpperCase>
</body>
</html>