一、foreach标签应用
1.1 tag类
package com.xqx.tag; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; /** * @author W许潜行 * */ public class ForeachTag extends BodyTagSupport{ //封装数据源,遍历数据 private List<Object> items = new ArrayList<>(); //封装对象指针:指向数据源中的对象 private String var; public ForeachTag() { // TODO Auto-generated constructor stub } 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()) { //得到第一个迭代器对象保存到对象指针中 pageContext.setAttribute(var, it.next()); //保存迭代后的迭代器对象 pageContext.setAttribute("it", it); return EVAL_BODY_AGAIN; } return SKIP_BODY; } @Override public int doStartTag() throws JspException { if(items==null||items.size()==0) return SKIP_BODY; //得到第一个迭代器对象 Iterator<Object> it = items.iterator(); //得到第一个迭代器对象保存到对象指针中 pageContext.setAttribute(var, it.next()); //保存迭代后的迭代器对象 pageContext.setAttribute("it", it); return EVAL_BODY_INCLUDE; } }
这个标签有三个属性:
“items”:需要遍历的集合对象。
“var”:迭代器指针指向的集合元素赋值变量名。
“body”:标签定义的标签体,其中可放置要循环执行的 JSP 代码块。
在 doStartTag() 方法中,首先判断集合对象是否为空,如果是则返回SKIP_BODY值,表示跳过标签体。如果非空,则获取迭代器对象,并将第一个迭代器对象赋值给对象指针,并将迭代器保存到 JSP 页面的 Attribute中,使其能够在后续方法中再次访问。
在 doAfterBody() 方法中,我们通过获取 Attribute中保存的迭代器对象,反复判断是否还有下一个元素。如果有,则将下一个元素赋值给对象指针,并将迭代器保存到 JSP 页面的 Attribute
中,以便在下一次迭代中使用。如果没有了,则返回 SKIP_BODY 值,表示跳过标签体。
1.2 tid
<?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"> <description>JSTL 1.1 core library</description> <display-name>JSTL core</display-name> <tlib-version>1.1</tlib-version> <short-name>c</short-name> <uri>http://jsp.xqx.cn</uri> <tag> <name>foreach</name> <tag-class>com.xqx.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> <tag> <name>Goods</name> <tag-class>com.xqx.tag.GoodsTag</tag-class> <body-content>JSP</body-content> <attribute> <name>var</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> <tag> <name>select</name> <tag-class>com.xqx.tag.SelectTag</tag-class> <body-content>JSP</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>optionVal</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>optionText</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>
在这个标签库描述文件中,定义了对应标签的名称、实现类和属性。其中, 元素用于定义标签属性,包括名称、是否必需、是否支持表达式等。 元素用于指定标签体中可放置的内容类型。
1.3 jsp
<%@page import="com.xqx.tag.Goods"%> <%@page import="java.util.ArrayList"%> <%@page import="java.util.List"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri = "http://jsp.xqx.cn" prefix = "x" %> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %> <!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<Goods> list = new ArrayList(); list.add(new Goods(1,"汽车")); list.add(new Goods(2,"飞机")); list.add(new Goods(3,"轮船")); request.setAttribute("list", list); %> <p>这是c标签的foreach <c:forEach items = "${list }" var = "l"> ${l.id }:${l.type } <hr/> </c:forEach> <h1>这是自定义标签的foreach</h1> <x:foreach items="${list }" var="l"> ${l.id }:${l.type } <hr/> </x:foreach> <x:Goods var="goods"> </x:Goods> 交通商品1:${goods } </body> </html>
首先在 JSP 页面中定义了一个商品列表集合对象,然后将其保存到请求属性中。
之后使用了两个循环遍历集合对象并将其中的元素逐个显示出来
其中一个是使用 JSTL 标签库中的 <c:forEach>
标签,另一个则是使用自定义标签库中的 <x:foreach> 标签。
二、数据标签
2.1tag类
package com.xqx.tag; import java.util.ArrayList; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; /** * @author W许潜行 * */ public class GoodsTag extends BodyTagSupport{ //封装一个保存数据的变量 private String var; public String getVar() { return var; } public void setVar(String var) { this.var = var; } @Override public int doStartTag() throws JspException { //模拟数据库传来的数据 List<Goods> list = new ArrayList<>(); list.add(new Goods(1,"汽车")); list.add(new Goods(2,"飞机")); list.add(new Goods(3,"轮船")); //将数据保存到封装的变量中 pageContext.setAttribute(var, list); return SKIP_BODY; } }
定义了一个变量var,用于保存商品列表,并提供了对该变量的getter和setter方法。
在doStartTag方法中,模拟了一个数据库返回商品列表的场景,并将该列表保存在了封装变量var中。在JSP页面中,通过调用该标签即可获取到商品列表,方便进行商品展示。
2.2jsp页面的调用
<x:Goods var="goods"> </x:Goods> 交通商品1:${goods } </body> </html>
其他页面也可以调用
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri = "http://jsp.xqx.cn" prefix = "x" %> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %> <!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> <x:Goods var="goods"> </x:Goods> 交通商品2:${goods } </body> </html>