最近公司跟别的公司合作天发一个项目,用到了那家公司自己开发的一套开发框架,其中包括了很多自定义标签很是方便,其中也有迭代标签,很方便。之前没有玩过自定义标签,于是在网上找了一些这方面的资料,了解了解其中的原理。然后自己写了一个简单的迭代标签。其中包括两个标签Collection、CollectionItem,都继承了BodyTagSupport。代码如下:
tld文件
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" 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">
<tlib-version>1.0</tlib-version>
<short-name>mytag</short-name>
<uri>/WEB-INF/tlds/mytag</uri>
<tag>
<name>collection</name>
<tag-class>com.jquery.mytags.Collection</tag-class>
<body-content>jsp</body-content>
<attribute>
<name>dataSource</name>
<required>true</required>
</attribute>
</tag>
<tag>
<name>collectionItom</name>
<tag-class>com.jquery.mytags.CollectionItem</tag-class>
<body-content>empty</body-content>
<attribute>
<name>property</name>
<required>true</required>
</attribute>
<attribute>
<name>title</name>
<required>false</required>
</attribute>
</tag>
</taglib>
web.xml中加入以下代码
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/tlds/mytag</taglib-uri>
<taglib-location>/WEB-INF/mytld/jquery-helloworld.tld</taglib-location>
</taglib>
</jsp-config>
Collection处理代码
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class Collection extends BodyTagSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private PageContext pageContext;
private String dataSource;// 数据源名称
@SuppressWarnings("unchecked")
private Iterator iter;
public String getDataSource() {
return dataSource;
}
public void setDataSource(String dataSource) {
this.dataSource = dataSource;
}
public Collection() {
super();
}
public int doAfterBody() throws JspException {
if(iter.hasNext()){
try {
pageContext.getOut().print("</tr>");
pageContext.setAttribute(dataSource,iter.next());
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_BODY_AGAIN;//表示循环处理标签体
}
return SKIP_BODY;
}
public int doEndTag() throws JspException {
try {
pageContext.getOut().print("</table>");
} catch (IOException e) {
e.printStackTrace();
}
return EVAL_PAGE;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException {
java.util.Collection coll = (java.util.Collection) pageContext.findAttribute(dataSource);
// 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
if (coll == null || coll.isEmpty())
return SKIP_BODY;
try {
pageContext.getOut().print("<table><tr>");
} catch (IOException e) {
e.printStackTrace();
}
iter = coll.iterator();
pageContext.setAttribute(dataSource,"setHeader");//处理列表表头
// 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
return EVAL_BODY_INCLUDE;
}
public void release() {
}
public void setPageContext(PageContext arg0) {
pageContext = arg0;
}
// 在doInitBody方法之前执行,在这里被绕过不执行
public void setBodyContent(BodyContent arg0) {
System.out.println("setBodyContent...");
super.setBodyContent(arg0);
}
// 此方法被绕过不会被执行
public void doInitBody() throws JspException {
System.out.println("doInitBody...");
super.doInitBody();
}
}
CollectionItem处理代码
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;
public class CollectionItem extends BodyTagSupport {
/**
*
*/
private static final long serialVersionUID = 2093044170883495102L;
private PageContext pageContext;
private Tag parent;
private String property;//打印字段名
private String width;//列宽
private String title;//标题
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public CollectionItem() {
super();
}
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
@SuppressWarnings("unchecked")
public int doStartTag() throws JspException {
try {
String dataSourceName = ((Collection)parent).getDataSource();
Object objItem = pageContext.getAttribute(dataSourceName);
if (objItem == null) return SKIP_BODY;
//判断是否是打印表头
if(objItem.toString()=="setHeader"){
String itemTile = title==null?property:title;//如果没写标题,刚表头显示为该列的字段名
pageContext.getOut().write("<td>"+itemTile+"</td>");
return SKIP_BODY;
}
Class cItem = objItem.getClass();
String itemStr = "";
Method method;
if(cItem==Map.class||cItem==HashMap.class||cItem==Hashtable.class){
method = cItem.getMethod("get",Object.class);
itemStr = (String) method.invoke(objItem,property);
}
else{
String getMethodNao = "get"+property.substring(0,1).toUpperCase()+property.substring(1);
method = cItem.getMethod(getMethodNao);
itemStr = (String) method.invoke(objItem);
}
String result="<td>"+itemStr;
result +="</td>";
pageContext.getOut().write(result);
} catch (Exception e) {
throw new JspTagException("IO Error: " + e.getMessage());
}
return SKIP_BODY;
}
public Tag getParent() {
return parent;
}
public void release() {
}
public void setPageContext(PageContext arg0) {
this.pageContext = arg0;
}
public void setParent(Tag arg0) {
parent = arg0;
}
}
doStartTag()和doEndTag()、doAfterBody()方法的返回值说明:
SKIP_BODY 表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE 忽略标签后面的jsp内容。
EVAL_PAGE 处理标签后,继续处理jsp后面的内容。
EVAL_BODY_BUFFERED 表示需要处理标签体,且需要重新创建一个缓冲(调用setBodyContent方法)。
EVAL_BODY_INCLUDE 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN 对标签体循环处理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)
Jsp应用代码
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<%@taglib uri="/WEB-INF/tlds/mytag" prefix="hello" %>
<!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=GBK">
<title>Insert title here</title>
<script type="text/javascript" src="../js/jquery-1.3.1.js"></script>
<script type="text/javascript">
$(document).ready(function(){
window.location.href = "../collectionSource.do";
});
</script>
</head>
<body>
<hello:collection dataSource="userList">
<hello:collectionItom property="userName" title="用户名"/>
<hello:collectionItom property="address" title="地址"/>
</hello:collection>
</body>
</html>
Action代码
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
Person p1 = new Person();
Person p2 = new Person();
Map p3 = new HashMap();
p1.setUserId(1111);
p1.setAddress("北京");
p1.setAge(25);
p1.setPassWord("12345");
p1.setUserName("张三");
p2.setUserId(1111);
p2.setAddress("上海");
p2.setAge(25);
p2.setPassWord("12345");
p2.setUserName("李四");
p3.put("address", "广州");
p3.put("age", 30);
p3.put("passWord", "12345");
p3.put("userName", "王五");
ArrayList arr = new ArrayList();
arr.add(p1);
arr.add(p2);
arr.add(p3);
request.setAttribute("userList", arr);
return mapping.findForward("jspView");
}
分享到:
相关推荐
### JSP自定义迭代标签详解 #### 一、引言 在JSP(JavaServer Pages)开发中,自定义标签可以极大地提高代码的复用性和可维护性。特别是在处理循环迭代逻辑时,自定义迭代标签能够使页面逻辑更加清晰、简洁。本文...
例如,自定义标签可以处理特定业务逻辑,而JSTL则负责通用的控制流、迭代和I/O操作。 总结,通过自定义标签,我们可以构建出强大的JSP组件,提高代码复用性和可维护性。理解并掌握自定义标签的原理和实践,对于提升...
而`Tag`接口是经典接口,通常需要实现`IterationTag`,用于处理迭代标签。 `TagSupport`和`BodyTagSupport`是这两个接口的实现类,它们提供了默认的行为和属性管理,简化了自定义标签的开发。`BodyTag`是`...
京东作为国内知名的电商平台,其商品评价系统独具特色,特别是自定义标签功能,为用户提供了一种直观、简洁的方式来理解和评估商品质量。本教程将深入探讨如何仿照京东的商品评价体系,实现自定义标签功能。 一、...
此外,自定义标签还可以支持更复杂的逻辑,如迭代、条件判断等,通过组合使用可以构建出强大的视图层模板。 学习和实践自定义标签有助于提升Java Web开发能力,使开发者能够更好地组织和复用代码,提高项目的可维护...
3. **无体迭代标签执行方法**: - `doStartTag`: 处理标签开始部分。 - `doEndTag`: 处理标签结束部分。 - `release`: 清理资源。 4. **体迭代标签执行方法**: - `doStartTag`: 处理标签开始部分。 - `...
JSTL允许开发者使用预定义的标签来处理常见任务,如迭代、条件判断、XML处理等。本文将深入讲解如何创建并使用JSTL自定义标签。 **一、自定义标签的实现** 1. **标签处理类(.java)** - 类需要继承`TagSupport`...
它提供了控制流标签(如if、choose、when、otherwise)、迭代标签(如forEach、forTokens)以及URL操作标签(如url、param)等。这个库文件是使用JSTL时必不可少的。 `standard.jar`是JSTL的补充库,主要包含了EL...
例如,`<c:forEach>`用于迭代集合,`<fmt:formatDate>`用于格式化日期,这些都是JSTL的核心标签。 自定义JSTL标签的创建涉及到以下几个步骤: 1. **创建Tag Handler类**:这是处理自定义标签逻辑的Java类,需要...
总结来说,"简单JSP标签实现迭代"这个实例涉及了JSP自定义标签的创建和使用,包括TLD文件的配置、标签处理类的编写以及标签文件的设计。通过这种方式,我们可以更好地组织和管理代码,提高开发效率,并使得JSP页面...
2. **迭代标签**: 遍历集合并多次输出内容,如foreach标签。 3. **身体标签**: 包含一个或多个动态生成的JSP片段作为其内容,如。 **自定义标签的使用** 在JSP页面中,可以通过`<jsp:taglib>`指令引入自定义标签库...
JSTL提供了许多内置标签来处理常见的任务,如迭代、条件判断、XML处理等。在这个场景中,我们要讨论的是如何使用JSTL来自定义标签,并将一个`int`类型的值转换为时间格式。 首先,理解自定义标签的创建过程是必要的...
例如,`JSTL`(JSP Standard Tag Library)就是一个常用的标签库,提供了用于处理常见任务的标签,如迭代、条件判断等。 2. **标签处理程序**:标签处理程序是Java类,它们实现了`Tag`、`IterationTag`或`BodyTag`...
迭代标签用于循环处理一组数据,如遍历集合。模板标签库则提供了一组通用的标签,可以用于构建常见的页面布局和组件。 【Tag Handler 类的调用过程】 当 JSP 引擎遇到自定义标签时,它会根据 TLD 文件找到对应的 ...
Struts 是一个强大的Java Web应用程序开发框架,它提供了一套丰富的自定义标签库,使得开发者在构建用户界面时能够更加方便地处理业务逻辑和数据展示。本文将详细讲解Struts中的Bean Tags、HTML Tags和Logic Tags的...
本文将深入探讨“JSP自定义标签”如何实现无限级树结构,并支持节点图标自定义,以及其背后的原理和技术要点。 首先,我们要理解什么是自定义标签。在JSP中,自定义标签是开发者为了简化页面逻辑、提高代码复用性而...
JSP提供了内置的`<c:forEach>`标签来实现这一功能,但对于自定义标签,我们需要在处理类中进行迭代,并在`doAfterBody()`方法中处理每个迭代项。我们可以使用`javax.servlet.jsp.PageContext`对象来存储数据,并在...
在这个名为“Jsp自定义标签通用数据库查询”的项目中,我们探讨的关键知识点是如何利用自定义标签实现一个通用的数据库查询功能,使其能够适用于多种数据库系统。 首先,我们需要了解JSP自定义标签的工作原理。...
Taglib是JSP标准标签库(JSTL)的一部分,它提供了一系列预定义的标签,用于简化JSP页面中的常见任务,如迭代、条件判断等。同时,开发人员还可以创建自己的自定义标签库,以满足特定项目需求。 ### 二、自定义标签...
为了实现自定义的file标签,我们需要利用HTML、CSS以及JavaScript(可能还需要一些库或框架如jQuery)来改造这个基本控件,以达到与网站整体风格一致的效果。 首先,我们需要创建一个HTML结构,用自定义的按钮或者...