JSP自定义标签开发入门
一般情况下开发jsp自定义标签需要引用以下两个包
import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*;
首先我们需要大致了解开发自定义标签所涉及到的接口与类的层次结构(其中SimpleTag接口与SimpleTagSupport类是JSP2.0中新引入的)。
目标1:自定义一个用表格显示用户信息的简单标签
效果图:
在jsp页面使用此自定义标签:
假设我们有一个UserInfo的javabean,那么在JSP页面使用此标签只需调用此标签即可
<%
UserInfo user = new UserInfo(); user.setUserName(\"Xuwei\"); user.setAge(33);
user.setEmail(\"test@test.test\");
pageContext.setAttribute(\"userinfo\ %>
开发步骤:
简单标签的开发我们只要实现Tag接口即可,为了简单起见可以直接继承实现了此接口的TagSupport类
1 创建自定义标签类
public class UserInfoTag extends TagSupport {
private UserInfo user;
@Override
public int doStartTag() throws JspException { try {
JspWriter out = this.pageContext.getOut(); if(user == null) {
out.println(\"No UserInfo Found...\"); return SKIP_BODY; }
out.println(\"
Username: | \"); out.println(\"\" + user.getUserName() + \" | \"); out.println(\"
Age: | \");\" + user.getAge() + \" | \"); out.println(\"
Email: | \");\" + user.getEmail() + \" | \"); out.println(\"
throw new JspException(e.getMessage()); }
return SKIP_BODY; }
@Override
public int doEndTag() throws JspException { return EVAL_PAGE; }
@Override
public void release() { super.release(); this.user = null; }
//getter and setters public UserInfo getUser() { return user; }
public void setUser(UserInfo user) { this.user = user; } }
2 在Web-Inf创建标签库描述文件.tdl(Tag Library Description)
3 配置web.xml
4 在需要使用此标签的jsp页面头部引入
<%@ taglib uri=\"/mytaglib\" prefix=\"cc\"%>
5 使用(参照上面的使用步骤)
此致,一个简单的JSP标签开发完成
标签类说明:
我们创建的UserInfoTag类继承了TagSupport类,而它又实现了Tag接口,Tag接口的生命周期由其所在的容器控制,如下图:
setPageContext() 将所在jsp页面的pageContext注入进来,目的是为了在后面的方法中可以访问到jsp页面对象的pageContext属性
setParent() 设置此标签的父标签
setAttribute() 将标签中的属性注入到此class的属性,不需要自己实现但要提供属性的get与set方法
doStartTag() 在开始标签属性设置后调用,如果返回SKIP_BODY则忽略标签之中的内容,如果返回EVAL_BODY_INCLUDE则将标签体的内容进行输出
doEndTag() 在结束标签之前调用,返回SKIP_PAGE跳过整个jsp页面后面的输出,返回EVAL_PAGE执行页面余下部分
release() 生命周期结束时调用
特别说明:在tomcat4.1之后的版本中默认开启了标签缓冲池 (websphere和weblogic并不会这么做),所以执行完标签后并不会执行release()方法
(_jspDestroy()时才释放),也 就是说同一个jsp页面自定义标签不管使用多少次只会存在一个实例,但也并不是每一个标签都会为其创建一个缓冲池,要根据参数来判断,例如:
上面例子中由于参数不同就会创建两个标签缓冲池。
这个问题可以通过设定tomcat的配置文件加以解决:
在%tomcat%\\conf\\web.xml加入enablePooling参数,并设置为false(不缓存自定义标签)。
清空%tomcat%\\conf\\目录
-------------------------------------------------------------------------------------------------------------------------------
TagSupport类已经为我们实现并扩展了一些方法(比如在上述方法中我们可以直接使用pageContext对象,调用父标签getParent()等),所以一般情况下我们只需重写doStartTag(),doEndTag() 即可
TLD文件说明:
Web.xml文件说明:
目标2:自定义一个类似于Asp.Net中的Reapter控件的标签
效果图:
在jsp页面使用此自定义标签:
<%
List users.add(new UserInfo(\"Zhangsan\ users.add(new UserInfo(\"Lisi\ users.add(new UserInfo(\"Wangwu\ pageContext.setAttribute(\"users\%> 开发步骤: 要完成此控件我们需要实现一个迭代接口,即IterationTag,由于TagSupport同样实现了此接口,所以我们继承此类 1 创建自定义标签类 public class Repeater extends TagSupport { private Collection items; private Iterator it; private String var; @Override public int doStartTag() throws JspException { if(items == null || items.size() == 0) return SKIP_BODY; it = items.iterator(); if(it.hasNext()) { pageContext.setAttribute(var, it.next()); } return EVAL_BODY_INCLUDE; } @Override public int doAfterBody() throws JspException { if(it.hasNext()) { pageContext.setAttribute(var, it.next()); return EVAL_BODY_AGAIN; } return SKIP_BODY; } @Override public int doEndTag() throws JspException { return EVAL_PAGE; } public void setItems(Collection items) { this.items = items; } public void setVar(String var) { this.var = var; } } 2在Web-Inf创建标签库描述文件.tdl(Tag Library Description) 由于目标1种已经创建了此文件,我们只需增加此标签的配置即可 3 配置web.xml (目标1中已完成,无需修改) 4 在需要使用此标签的jsp页面头部引入 <%@ taglib uri=\"/mytaglib\" prefix=\"cc\"%> 5 使用(参照上面的使用步骤) 标签类说明: 我们用到了迭代接口,以下是容器处理此接口的流程 作为目标1中的补充: 在doAfterBody()如果返回值是EVAL_BODY_AGAIN那么将重新执行此方法 目标3:使用BodyTagSupport 此目标并不会使用实际例子进行显示,主要是说明为什么,什么情况下需要使用到BodyTag接口或者BodyTagSupport类? 如果我们需要在 是如果是个迭代标签,标签体的每段内容在循环输出时每次都需要在头部和尾部加上一些标记,我们使用BodyTagSupport就很方便了, 此接口在doStartTag()方法返回值多了一个EVAL_BODY_BUFFERED,它将对主体进行计算,并输出到缓冲区(注:此处是缓冲 区并非直接输出到客户端,需要我们手动 (this.bodyContent.getEnclosingWriter().write(this.bodyContent.getString());) 进行输出客户端的调用,否则主体内容不会进行显示) 标签类说明: 关于BodyTagSupport接口的说明 目标4:自定义的函数库 1 创建函数库类 public class MyFunctions { public static String formatMyName(String name) { return \"your name is \" + name; } public static int add(int a, int b) { return a+b; } } 2 在TLD文件中配置 (引用于目标1中的tld文件) formatMyName(java.lang.String) 3 JSP中调用 ${cc:formatMyName(\"wangfei\") } ${cc:add(12, 34) } http://blog.csdn.net/awusoft/article/details/3761514 自定义嵌套标签实现IF ELSE 2009-01-12 17:29 1544人阅读 评论(0) 收藏 举报 nulllistencodingstring 三个标签类:PowerIfTag是外边的,用来判断,PowerYesTag是里边的表示if(true)时,PowerNoTag是else] PowerIfTag.java 1. package aa; 2. import java.io.IOException; 3. 4. import javax.servlet.jsp.JspException; 5. import javax.servlet.jsp.JspTagException; 6. import javax.servlet.jsp.JspWriter; 7. import javax.servlet.jsp.tagext.TagSupport; 8. 9. public class PowerIfTag extends TagSupport { 10. private String list; 11. private String name; 12. private boolean is; 13. 14. public boolean isIs() { 15. return is; 16. } 17. 18. public void setIs(boolean is) { 19. this.is = is; 20. } 21. 22. public String getList() { 23. return list; 24. } 25. 26. public void setList(String list) { 27. this.list = list; 28. } 29. 30. public String getName() { 31. return name; 32. } 33. 34. public void setName(String name) { 35. this.name = name; 36. } 37. 38. public int doStartTag() throws JspException { 39. if(name!=null && !name.equals(\"\") && list!=null && !list.equals(\"\")) 40. { 41. //以下关键代码,大家可以根据自己的需求来改变. 42. Object o = this.pageContext.getSession().getAttribute(name); 43. if(o instanceof String) 44. { 45. String aStr[]=list.split(\46. String oStr = (String)o; 47. for(int i=0;i 51. this.is = true; 52. break; 53. } 54. } 55. } 56. }else 57. { 58. this.is = false; 59. } 60. return this.EVAL_PAGE; 61. } 62. } 63. PowerYesTag.java 1. package aa; 2. 3. import java.io.IOException; 4. 5. import javax.servlet.jsp.JspException; 6. import javax.servlet.jsp.JspTagException; 7. import javax.servlet.jsp.JspWriter; 8. import javax.servlet.jsp.tagext.Tag; 9. import javax.servlet.jsp.tagext.TagSupport; 10. 11. public class PowerYesTag extends TagSupport { 12. 13. public int doStartTag() throws JspException { 14. Tag t = findAncestorWithClass(this, PowerIfTag.class); 15. if(t!=null) 16. { 17. PowerIfTag parent = (PowerIfTag) t; 18. if(parent.isIs()) 19. { 20. return EVAL_PAGE; 21. } 22. } 23. return SKIP_BODY; 24. } 25. } 26. PowerNoTag.java 1. 2. 3. 4. 5. 6. 7. 8. package aa; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.Tag; 9. import javax.servlet.jsp.tagext.TagSupport; 10. 11. public class PowerNoTag extends TagSupport { 12. 13. public int doStartTag() throws JspException { 14. Tag t = findAncestorWithClass(this, PowerIfTag.class); 15. if(t!=null) 16. { 17. PowerIfTag parent = (PowerIfTag) t; 18. if(!parent.isIs()) 19. { 20. return EVAL_PAGE; 21. } 22. } 23. return SKIP_BODY; 24. } 25. } powerif.tld 1. 2. 3. 6. 7. 8. 10. 11. 12. 15. 17. 21. 22. 25. 26. ${company.companyCode} 为何要自定义标签,就是因为有些别人写的标签不一定会合适自己的需要.像我所写的是关于权限的判断.大家用的时候要注意灵活点. 修改PowerIfTag中的业务代码就可以根据需求来灵活变换,我现在是判断权限,大家也可以根据自己的项目需求来改变. 因篇幅问题不能全部显示,请点此查看更多更全内容
UserName Age Email ${item.userName } ${item.age } ${item.email }