自定义迭代标签

最近公司跟别的公司合作天发一个项目,用到了那家公司自己开发的一套开发框架,其中包括了很多自定义标签很是方便,其中也有迭代标签,很方便。之前没有玩过自定义标签,于是在网上找了一些这方面的资料,了解了解其中的原理。然后自己写了一个简单的迭代标签。其中包括两个标签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");
	}

你可能感兴趣的:(jquery,Web,jsp,xml,servlet)