使用自定义标签模拟jstl的<c:for each>标签
一.自定义标签的基本编写
下面编写一个自定义标签,它可以输出当前的时间.
1.编写标签类
类可以通过继承SimpleTagSupport类实现一个标签类编写.父类为我们提供了一些编写自定义标签的快捷的成员变量.而在服务器解析到自定义标签的时候,会去寻找标签类的doTag方法(这个方法在父类中有定义),并且将这些成员变量赋值.在开发中,用的最多的成员变量有2个,代表页面上下文的JspContext和代表标签内的内容的JspFragement.JSPContext对象实际上就是一个PageContext对象,它可以获得其他jsp的八大隐式对象,和存放数据.而JspFragement对象则提供了一些快捷操作标签内部内容的方法.两个对象分别通过getJspContext和getJspBody方法获得.下面给出了输出当前时间的标签类的编写:
public class PrintTag extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
PageContext pageContext = (PageContext) getJspContext();
pageContext.getOut().write(sdf.format(date));
}
}
可以通过pagecontext对象获得jsp内置对象out来输出数据.doTag方法,在jsp引擎解析到标签的时候调用.
2.创建一个配置文件,配置标签的相关属性.
1>在WEB-INF目录下建立一个后缀名为.tld的配置文件.在配置文件中引入下列模板:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<tlib-version>1.0</tlib-version>
<short-name>itheima</short-name>
<!--声明在taglib上的命名空间-->
<uri>http://www.xyy.com/tags</uri> </taglib>
2>在<tag>里声明标签的属性.
<tag>
<!-- 标签名.在前缀:后面添加的字符串 -->
<name>print</name>
<!-- 实现该标签的类 -->
<tag-class>com.xyy.tag.PrintTag</tag-class>
<!-- body-content没有标签的主体内容,用empty -->
<body-content>empty</body-content>
</tag>
<body-content>取值:
empty:没有主体内容。简单和传统标签都能用。
scriptless:给简单标签用的,说明主体内容是非脚本。(不能使用<%=%>这样的,但是EL表达式可以被正常解析)
tagdependent:把主体内容的EL表达式当做普通字符串对待。
3.在jsp页面用taglib引入,并且在页面中使用标签.


二.自定义标签的执行流程
执行流程如下图(需要注意的是标签处理类是线程安全的,每次访问带有标签的页面,标签处理类都会实例化.)

三.采用自定义标签模拟foreach标签.
1.首先在页面中将需要模拟的标签的基本形式编写好,页面如下:
<%@page import="java.util.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.yunyun.com/demo" prefix="demo"%>
<%@ 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<String> list=new ArrayList<String>();
list.add( "hlhdidi");
list.add("23岁");
list.add("7000");
%>
<%
Map<String,String> map=new HashMap<String,String>();
map.put("name", "hlhdidi");
map.put("age", "23岁");
map.put("salary", "7000元");
pageContext.setAttribute("map", map);
%>
<c:set value="<%=list %>" var="list" scope="request"></c:set>
<demo:foreach items="${list }" var="item" varstatus="vs">
${vs.count }---${item }
</demo:foreach>
<demo:foreach items="${map }" var="en" varstatus="vs">
${vs.count }---${en.key }:${en.value }
</demo:foreach>
</body>
</html>
可以看出,标签中需要传递三个参数.分别是items,var,以及varstatus.如果需要传递参数到标签类中,只需要在标签类中声明对应的成员变量即可.jsp引擎在发现这些参数的时候,将会自动寻找标签类的相应属性并且进行赋值.可以看出items必须是Object类型,而var和varstatus由于仅仅是传入PageContext域中的值的标识,所以采用字符串类型.
2.声明标签类.
for each标签需要将每一个遍历到的当前对象传入pageContext域中,同时将状态信息传入pageContext域中,因此建立Status类描述状态信息,为了简便,status类只定义了一个成员变量count,记录当前的循环次数.
public class Status implements Serializable{
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
由于items是Object的数据类型,因此需要对其进行类型判断,在标签类的内部采用Collection的引用进行接收标签的items传入的对象.随后在doTag方法中,将遍历的对象放入PageContext域中,随后执行展示的操作.这里采用getJspBody.invoke(null)方法.这个方法将会进行默认的标签内容展示.具体的标签类如下:
public class SimpleForEachTag extends SimpleTagSupport{
private String var;
private String varstatus;
private Object items;
/*用Collection的引用是因为,需要在将items传入的时候,实行强制转换.
如果用List或者Set来接收,那么当只能强转为List/Set.
因为,将一个类型的对象强制转化为一个不匹配的引用会报错,所以只能用Collecion来接收*/
private Collection list=new ArrayList();
public void setVar(String var) {
this.var = var;
}
public void setVarstatus(String varstatus) {
this.varstatus = varstatus;
}
//为了方便遍历,进行强制类型转换
public void setItems(Object items) {
//在这里会将items传入
if(items instanceof List) {
list=(List)items;
}
else if(items instanceof Set) {
list=(Set)items;
}
else if(items instanceof Map) {
list=((Map)items).entrySet();
}
else if(items instanceof Object[]) {
list=Arrays.asList((Object[])items);
}
}
@Override
public void doTag() throws JspException, IOException {
PageContext pageContext = (PageContext) getJspContext();
Status status=new Status();
int i=0;//循环次数
if(list!=null) {
for(Object obj:list) {
//放入pageContext域中
pageContext.setAttribute(var, obj);
status.setCount(++i);
pageContext.setAttribute(varstatus, status);
getJspBody().invoke(null); //默认的输出
}
}
}
}
3.配置标签.
配置如下:
<tag>
<name>foreach</name>
<tag-class>com.xyy.tag.SimpleForEachTag</tag-class>
<body-content>scriptless</body-content>
<!-- 设置属性的值 -->
<attribute>
<!-- 属性名 -->
<name>items</name>
<!-- 属性是否必须 -->
<required>true</required>
<!--
属性是否支持Java表达式/EL表达式.true为支持,false不支持
如果不支持的时候在设置属性时,如果写了EL表达式.会抛出异常
-->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>varstatus</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
四.总结
自定义标签是一个很有用的功能,可以通过最基本的自定义标签的学习,在jsp页面中完成我们想要的功能展示.
使用自定义标签模拟jstl的<c:for each>标签的更多相关文章
- JavaWeb(七):EL表达式、自定义标签和JSTL
一.EL表达式 语法 el.jsp <%@page import="java.util.Date"%> <%@page import="com.atgu ...
- 自定义标签 与 JSTL(JSP Standard Tag Library)
1.自定义标签 [理解] [1]简介 > 在JSP2.0以后,在jsp页面中不建议使用脚本片段<% %>和JSP表达式<%= %> ...
- 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签
学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签. jsp标签的分 ...
- JSP标签:jsp内置标签、jstl标签、自定义标签
一.jsp标签的分类: 1)内置标签(动作标签): 不需要在jsp页面导入标签 2)jstl标签: 需要在jsp页面中导入标签 3)自定义标签 : 开发者自行定义,需要在jsp页面导入标签 1 ...
- 自定义标签(JSTL)
自定义标签的步骤: 1.确定需求,如:用<my:date/>输出当前时间 2.编写Java类:需要实现实现接口javax.servlet.jsp.tagext.JspTag 具体的接口为: ...
- [原创]java WEB学习笔记40:简单标签概述(背景,使用一个标签,标签库的API,SimpleTag接口,创建一个自定义的标签的步骤 和简单实践)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- JSP 标准标签库(JSTL)
JSP 标准标签库(JSTL) JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签, ...
- JSTL标签,EL表达式,OGNL表达式,struts2标签 汇总
一下纯属个人总结摘抄,总结一起方便查看,解决疑问,有遗漏或错误,还请指出. 1,JSTL标签总结: a).JSTL标签有什么用? JSTL是由JCP(Java Commu ...
- JSTL标签库的基本教程之核心标签库(一)
JSTL介绍 Java Server Pages Standard Tag Libray(JSTL):JSP标准标签库,它封装了JSP应用的通用核心功能.JSTL支持通用的.结构化的任务,比如迭代,条 ...
随机推荐
- 夺命雷公狗-----React---24--小案例之react经典案例todos(单条任务的删除)
我们的组建分析图 我们组建需要的是删除,数据流方式如下所示: 为了更方便下一步操作,先写个函数他 然后在Ul组建里面对她进行处理 然后在Zong组建里对数据进行处理,如下所示: 但是悲剧的一幕出现了, ...
- web应用安全防御100技 好书再次阅读, 变的只是表象,被概念迷惑的时候还是静下心来回顾本质
如何进行web应用安全防御,是每个web安全从业者都会被问到的问题,非常不好回答,容易过于肤浅或流于理论,要阐明清楚,答案就是一本书的长度.而本文要介绍一本能很好回答这个问题的优秀书籍——<we ...
- 当java出现异常,应如何进行处理
Java异常是一个描述在代码段中发生的异常(也就是出错)情况的对象.当异常情况发生,一个代表该异常的对象被创建并且在导致该错误的方法中被抛出(throw).该方法可以选择自己处理异常或传递该异常.两种 ...
- Mysql中的少用函数
1.查询时需要转换类型,大多发生在数字和字符串.时间和字符串之间 Mysql提供了两个个类型转换函数:CAST和CONVERT CAST() 和CONVERT() 函数可用来获取一个类型的值,并产生另 ...
- CC_STACKPROTECTOR防内核堆栈溢出补丁分析【转】
转自:https://yq.aliyun.com/articles/1723 摘要: 作者:王智通 CC_STACKPROTECT补丁是Tejun Heo在09年给主线kernel提交的一个用来防 ...
- 【转载】移动web开发经验总结
本文出自: http://blog.163.com/hsb001_mobile/blog/static/15524028020111177221254/ 1.-webkit-tap-highlight ...
- 利用Maven打包时,如何包含更多的资源文件
首先,来看下MAVENx项目标准的目录结构: 一般情况下,我们用到的资源文件(各种xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包时,ma ...
- JavaScript- jquery easyui 可编辑表格插件 easyui.editgrid
最近项目前端使用 jquery+easyui来做,用了几个月,觉得easyui是一个很不错的开源前端UI框架, 虽然偶尔会遇到一些小问题,但是凭借多年前端开发的实力积累 都一一解决了,其中比较典型的就 ...
- Java 集合常用方法锦集
Java集合非常的重要,尤其在业务中,如果你在熟练的使用Java数据结果的集合工作,将会大大的提高工作效率,减少代码量. 1.集合的互换 1.1 Map转Set Map<Integer, Str ...
- Mybatis框架基于映射文件和配置文件的方式,实现增删改查,可以打印日志信息
首先在lib下导入: 与打印日志信息有关的架包 log4j-1.2.16.jar mybatis架包:mybatis-3.1.1.jar 连接数据库的架包:mysql-connector-java-5 ...