博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义JSP中的Taglib标签之三简单仿JSTL中带标签体的ForEach循环
阅读量:3741 次
发布时间:2019-05-22

本文共 4156 字,大约阅读时间需要 13 分钟。

上2篇文章分别了介绍了taglib的无属性状态和有带属性状态,但是都是分别都是独立的闭标签,这次带来的是带属性的和带标签体的例子,仿照jstl中的forEach循环构造一个简单的循环标签.

Java代码如下:

package org.lxh.taglib;import java.util.Collection;import java.util.Iterator;import java.util.Map;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.BodyTagSupport;public class TestForEach extends BodyTagSupport {	private static final long serialVersionUID = -5210136338413610356L;	private String var;	private Iterator
iterator; public String getVar() { return var; } public void setVar(String var) { this.var = var; } public void setItem(Object item) { if (item instanceof Map) { Map items = (Map) item; this.iterator = items.entrySet().iterator(); } else { Collection
c = (Collection) item; this.iterator = c.iterator(); } } @Override public int doAfterBody() throws JspException { if (this.process()) { return EVAL_BODY_AGAIN; } else { return EVAL_PAGE; } } @Override public int doStartTag() throws JspException { if (this.process()) return EVAL_BODY_INCLUDE; else return EVAL_PAGE; } private boolean process() { if (null != iterator && iterator.hasNext()) { Object item = iterator.next(); pageContext.setAttribute(var, item); return true; } else return false; }}

 

问题1:为什么要继承BodyTagSupport 而不去只实现IterationTag接口或者直接继承TagSupport使用呢?

TagSupport与BodyTagSupport的区别主要是标签处理类是否需要与标签体交互,如果不需要交互的就用TagSupport,否则如果不需要交互就用BodyTagSupport。
交互就是标签处理类是否要读取标签体的内容和改变标签体返回的内容。用TagSupport实现的标签,都可以用BodyTagSupport来实现,因为BodyTagSupport继承了TagSupport而不去实现IterationTag接口的,因为BodyTagSupport继承了TagSupport类,并且该类已经实现了IterationTag接口并且实现了功能.

doStartTag()方法在标签开始时执行,要记住每次都要对类进行初始化,避免上一次的遗留数据对操作造成影响。然后判断是否有数据需要处理,如果有,则返回EVAL_BODY_INCLUDE开始处理标签里的内容,如果没有,返回 EVAL_PAGE跳过标签内容执行标签下面的内容。

doAfterBody()方法在每次处理完标签内部内容后执行,判断循环是否已经结束,如果可以继续循环,返回EVAL_BODY_AGAIN用循环得到新的数据再次处理标签内部内容,如果循环结束就返回EVAL_PAGE结束标签。

tld如下:

1.0
for
foreach
org.lxh.taglib.TestForEach
org.lxh.tagei.ForEachInfo
JSP
var
true
true
item
true
java.lang.Object

是不是发现tld有点改变了,没错,如果要使用包含标签体的标签库的话需要在<body-content>标签中加入jsp,这样的话该标签表示可以包含jsp和html的标签进行一起循环,上面是否还发现多了一个<tei-class>标签,该标签用途就是对当前自定义的标签体进行验证检查的.

tei验证检查代码如下:

package org.lxh.tagei;import javax.servlet.jsp.tagext.TagData;import javax.servlet.jsp.tagext.TagExtraInfo;import javax.servlet.jsp.tagext.VariableInfo;public class ForEachInfo extends TagExtraInfo {	final private static String ITEMS = "item";	final private static String VAR = "var";	 @Override	 public VariableInfo[] getVariableInfo(TagData data) {	 return new VariableInfo[] {	 new VariableInfo(data.getAttributeString("var"),	 "java.lang.String", true, VariableInfo.AT_BEGIN),	 new VariableInfo(data.getAttribute("item").toString(),	 "java.lang.Object", true, VariableInfo.AT_BEGIN) };	 }	@Override	public boolean isValid(TagData us) {		if (!Util.isSpecified(us, ITEMS))			return false;		return true;	}}
public class Util {	/**	 * Returns true if the given attribute name is specified, false otherwise.	 */	public static boolean isSpecified(TagData data, String attributeName) {		return (data.getAttribute(attributeName) != null);	}

才用验证的好处非常之多的,可以对当前传入的值进行验证,还有非空的检查,在标签的时候如果不写某个标签体会出现验证为false的提示.
jsp代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="/WEB-INF/tld/testforeach.tld"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ">

<%@page import="java.util.*"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<%
    List<String> list = new ArrayList<String>();
    list.add("aa");
    list.add("bb");
    list.add("cc");
    Map map = new HashMap();
    map.put("1","a");
    map.put("2","b");
    map.put("3","c");
    map.put("4","b");
%>
<body>
<table>

    <c:foreach var="hi"  item="<%=map %>" >
        <tr>
            <td>${hi}</td>
        </tr>
    </c:foreach>
</table>
</body>
</html>

转载地址:http://oxlin.baihongyu.com/

你可能感兴趣的文章
python实现快速排序
查看>>
python实现归并排序
查看>>
二叉树的镜像实现(python版)
查看>>
ptqt5控件了解(三)
查看>>
自学C++(一)
查看>>
51单片机介绍(二)
查看>>
STM32F103 入门篇-5-初识STM32
查看>>
后台框架的frameset
查看>>
Spring Jdbc
查看>>
Spring 事务管理
查看>>
Spring中的Mybatis
查看>>
spring与mybatis的整合
查看>>
Spring Mvc
查看>>
Spring Mvc的核心类与注解
查看>>
json数据交换和RESTful支持
查看>>
spring中的拦截器
查看>>
文件上传和下载
查看>>
Oracle指令,软件架构,
查看>>
Oracle新建用户,授权,单表查询,连接符,去重,排序,逻辑运算,where子查询
查看>>
oracle5:oracle的图形界面操作,分页查询,练习
查看>>