一、实现遍历 List 集合、可以与自带的JSTL的forEach循环实现双(多)重循环
1.编写 JAVA 类
import javax.servlet.jsp.tagext.SimpleTagSupport; // 要导入的 包
import javax.servlet.jsp.JspException;
//1.定义JAVA类、实现 SimpleTagSupport 接口
public class ForEachList extends SimpleTagSupport {
//2.定义属性、并给出 gette 、setter 方法
private Object items; // 用于接收输入的值
private String var; // 用户输出的值
//3.重写 doTag() 方法
public void doTag() throws JspException, IOException{
//4.编写逻辑控制语句
// 判断是不是 List 集合
if(items instanceof List){
// 强转为 list 集合
List list = (List)items;
// 使用 foreach 循环遍历
for (Object obj : list) {
//输出内容
getJspContext().setAttribute(var, obj);
//输出标签体
getJspBody().invoke(null);
}
}else{
throw new JspException("只能遍历 List 集合!");
}
}
}
2.编写 *.tld 文件(在 WEB-INF 下创建)
<taglib xmlns="http://Java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>this is my tag library Definition</description>
<tlib-version>1.0</tlib-version>
<short-name>mytaglib</short-name>
<!-- 用于指定在调用时的 uri -->
<uri>http://127.0.0.0/servlet/mytaglib</uri>
<!-- 创建标签 -->
<tag>
<!-- 标签名 -->
<name>foreach</name>
<!-- 给自己定义用于实现 自定义的 JSTL 标签的类 的全限定名 -->
<tag-class>cn.jbit.auction.myjstl.ForEachList</tag-class>
<body-content>scriptless</body-content>
<!-- 指定foreach循环中的items属性和var属性 -->
<attribute>
<name>items</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<fragment>true</fragment>
</attribute>
</tag>
</taglib>
6.在 jsp 页面中调用
<%-- 导入自带的 JSTL 标签 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%-- 导入自定义的 JSTL 标签 --%>
<%@taglib uri="http://127.0.0.0/servlet/mytaglib" prefix="m"%>
<%-- 使用自定义JSTL标签 实现循环 --%>
<%-- 创建循环 所使用的 LIST 集合 --%>
<%
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
// 保存到 session 中 也可以不保存 使用 EL 表达式都能获取
session.setAttribute("list",list);
%>
<%--
调用 遍历 LIST 集合
m: 为导入自定义标签 的 prefix 值
foreach:是在 *.tld 文件中的标签名 <name>foreach</name>
var: 为输出属性
items: 用于输入数据属性
--%>
<m:foreach var="s" items="${list }">
${s } <%-- 输出值 --%>
</m:foreach>
<%-- 与自带的 forEach 循环实现双重循环 --%>
<%-- 创建循环 所使用的 LIST 集合 --%>
<%
List<String> list1 = new ArrayList<String>();
list1.add("a");
list1.add("b");
list1.add("c");
list1.add("d");
List<String> list2 = new ArrayList<String>();
list2.add("a");
list2.add("b");
list2.add("c");
list2.add("d");
// 在这个集合中放了两个 List 集合
List<List> list = new ArrayList<List>();
list.add(list1);
list.add(list2);
// 保存到 session 中 也可以不保存 使用 EL 表达式都能获取
session.setAttribute("list",list);
%>
<%--
调用 遍历 LIST 集合
外层循环为 自带的、内层循环为 自定义的
c:forEach 是自带的
m: 为导入自定义标签 的 prefix 值
foreach:是在 *.tld 文件中的标签名 <name>foreach</name>
var: 为输出属性
items: 用于输入数据属性
--%>
<c:forEach var="li" items="${list }">
<m:foreach var="s" items="${li }">
${s } <%-- 输出值 --%>
</m:foreach>
</c:forEach>
7.注意事项
使用 EL 表达式时注意
示:items="${list }" // 在{} 中 list 后面可以有空格 ${} 后面到 " 不能为空格、会导致发生错误
正确:items="${list }" 或 items="${list}"
错误:items="${list } " 或 items="${list } "
二、simpleTag接口中的方法:
以下三个方法的共同特点:由服务器调用,在调用doTag之前就调完了。
void doTag():由服务器调用。在JSP中遇到标签时调用。在自定义标签类中要重写的方法
void setJspBody(JspFragment jspBody):由服务器调用。传入标签的内容。
void setJspContext(JspContext pc):由服务器调用。传入当前页面的pageContext对象
void setParent(JspTag parent):由服务器调用。传入你的爹。没爹传入null
在自定义标签中 常调用方法
Object getJspContext():获取 pageContext对象
示:Object obj = getJspContext().getAttribute("name"); // 获取pageContext域中的保存的数据
JspTag getParent():由程序员调用。获取该标签的父标签对象。没有返回null
JspFragment jf=getJspBody();//获得主体内容
三、标签的实际作用
获得主体内容并输出:
JspFragment jf=getJspBody();
jf.invoke(null);
简易写法:
getJspBody().invoke(null);
1.使得主体内容不显示
<body-content>scriptless</body-content>//主体内容为非脚本
2.控制结束标签后的内容不执行
throw new SkipPageException();
3.控制主体内容重复运行
在类中写入循环代码即可
循环输出主体内容代码体现:
jsp:<itcast:ShowFor count="5">saq</itcast:ShowFor> //count为标签属性
*.tld 文件
itcast.tld:
<tag>
<name>ShowFor</name>
<tag-class>text.jsp.ShowFor</tag-class>
<body-content>scriptless</body-content>
//配置属性
<attribute>
<name>count</name>//属性名
<required>true</required>//是否必须输入属性值
<rtexprvalue>true</rtexprvalue>//是否支持表达式
</attribute>
</tag>
类:
public class ShowFor extends SimpleTagSupport {
private int count;
// 省略 getter 和 setter 方法
public void doTag() throws JspException, IOException {
for(int i=0;i<count;i++){
getJspBody().invoke(null);//输出主体内容,当为null时,就输出主体内容
}
}
}
4.获取主体内容,并操作主体内容后输出
public void doTag() throws JspException, IOException {
//获取主体内容
JspFragment jf=getJspBody();
//将主体内容写入字符缓存
StringWriter sw=new StringWriter();
jf.invoke(sw);
//调用string的大写转换方法
String jfString=sw.getBuffer().toString();
jfString=jfString.toUpperCase();
//输出
PageContext pc=(PageContext) getJspContext();
pc.getOut().write(jfString);
}
body-content中的内容:
1 jsp 不考虑,传统标签处理类中
2 empty 传统标签和普通标签都能用,主体中不能有内容
3 scriptless 简单标签使用,要求主体中有内容,但不能有“<”“%”,可以有EL表达式,但不能有java表达式
4 tagdependent 简单标签使用,告诉类,主体标签中的为文本
浙公网安备 33010602011771号