1. 开发遍历所有类型数据的标签
标签处理类: package com.csdn.web.example; import java.io.IOException; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; publicclass ForEachAll extends SimpleTagSupport{ private Collection collection; private String var; private Object items; publicvoid setVar(String var) { this.var = var; } publicvoid setItems(Object items) { this.items = items; } @Override publicvoid doTag() throws JspException, IOException { //判断是否是Map 下面的三个判断可以在doTage()方法中也可以在setItems()方法中 if(itemsinstanceof Map){ //这里要把jsp页面传进来的属性强转为Map类型,不能new HashMap Map map = (Map) items; collection = map.entrySet(); } //判断是否是set、list if(itemsinstanceof Collection){ collection = (Collection) items; } //判断是否是数组,各种数组 if(items.getClass().isArray()){ collection = new ArrayList(); int len = Array.getLength(items); for(int i=0;i<len;i++){ collection .add( Array.get(items, i)); } } Iterator it = collection.iterator(); while(it.hasNext()){ Object obj = it.next(); this.getJspContext().setAttribute(var,obj); this.getJspBody().invoke(null); } } } Jsp文件 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="example" prefix="example"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>遍历各种类型数据</title> </head> <body> <% List list = new ArrayList(); list.add(1); list.add("aa"); list.add("bb"); list.add(2); request.setAttribute("list",list); %> <example:forEachAll var="str" items="${list}"> ${ str }<br> </example:forEachAll> <hr> <% Map map = new HashMap(); map.put("1","aa"); map.put(2,"aa"); map.put(3,"aa"); map.put(4,"aa"); request.setAttribute("map",map); %> <example:forEachAll items="${map}" var="map"> ${ map.key}-------${ map.value }<br> </example:forEachAll> <hr> <% String[] strs = {"asd","fff","v","tt"}; request.setAttribute("strs",strs); %> <example:forEachAll items="${strs}" var="str">${str}<br></example:forEachAll> <hr> <% int[] i = {1,2,3,4}; request.setAttribute("i",i); %> <example:forEachAll items="${i}" var="num">${num}<br> </example:forEachAll> </body> </html> 注:描述文件与前面博客的forEach标签的定义一样,这里就不啰嗦的列出,不懂的可以去看上一篇博客 2. 开发html转义标签案例分析: 标签处理类: package com.csdn.web.example; import java.io.IOException; import java.io.StringWriter; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; publicclass HtmlFilter extends SimpleTagSupport { @Override publicvoid doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); StringWriter sw = new StringWriter(); jf.invoke(sw); String s = sw.toString(); s = filter(s); this.getJspContext().getOut().write(s); } //这个模版文件tomcat下也有,可以参考那个。转移标签模版文件: D:\java\Tomcat\apache-tomcat-6.0.18\webapps\examples\WEB-INF\classes\util public String filter(String message) { if (message == null) return (null); char content[] = newchar[message.length()]; message.getChars(0, message.length(), content, 0); StringBuffer result = new StringBuffer(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case'<': result.append("<"); break; case'>': result.append(">"); break; case'&': result.append("&"); break; case'"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } } JSP文件 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="example" prefix="example" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>自定义转义标签</title> </head> <body> <example:HtmlFilter> <a href="">自定义转义标签</a> </example:HtmlFilter> </body> </html>
3. 自定义标签不报错,但是结果不对的原因及处理:
情况一:检查你的jsp页面上的taglib指令是否写了,如果写了,在检查一下你的uri路径是否正确;如果都正确,再看看你的tld描述文件中的tag标签定义的是否正确,它中的uri类路径是否正确,起的名字是否一致。
情况二:检查你的标签处理类是否正确,主要错误有你是不是忘了写输出到浏览器的代码,有两种形式:1).this.getJspContext().getOut().write(s);2).this.getJspBody.invoke(null);这两种输出分别是不同的输出,后者是JspFragment
类对象的输出,直接输出null就相当于情况一的输出;还有一点要注意的是:invoke()方法可以直接输出到浏览器也可以给它传一个流参数,常用的是StringWriter字符输出流,这是两种输出要同时配合使用,比如:
spFragment jf = this.getJspBody();
StringWriter sw = new StringWriter();
jf.invoke(sw);
String s = sw.toString();
s = filter(s);
this.getJspContext().getOut().write(s);
但是大多数人会忘了最后一句的输出浏览器的代码,这是就是情况二常犯的错误了
4. 打包标签库
一般情况下直接打包就行,但是有时候打出来的包不能用,还需要导入你class文件中需要的类文件jar包,这时候你需要到tomcat下的,比如我的是D:\java\Tomcat\apache-tomcat-6.0.18\lib这个路径下导入jsp-api.jar和servlet-api.jar这两个文件。
把自定义的标签打到一个jar包中,就是要把标签处理类的字节码和标签库描述文件按照一定的存放方式添加到一个jar包中。具体做法如下。把标签处理类字节码和标签库描述文件按如下所示的结构组织。
标签库描述符文件要放置在jar文件的META-INF目录下(这里注意META-INF的书写不要误写成MEAT-INF,本人就爱范这种低级错误,一定要正确,稍微写错一点就会导致打出来的包不能用);标签处理类字节码的根目录和META-INF目录平级放置。
可以利用myeclipse工具倒包,前面博客具体介绍过,这里再简单说一下:就是右键导出(export)项目,选择java下的jar文件。具体如下图所示
如上图显示的.classpath和.project是jar包不需要的,可以不打进包中,所以不用勾选,然后点击Browse选择一个路径输出jar包,这就完成了打包,注意:这里是建一个java项目然后打包。打出来的是jar包用web项目打出的是war包。
也可以使用jar命令来创建jar文件,具体做法如下:jar cvf mytaglib_0.9.jar META-INF(描述文件) com(class字节码)完成这两个步骤之后,一个自定义标签库jar包就打好了,可以把它添加到任何想使用这个标签库的Web应用程序的WEB-INF/lib目录下使用了。