`
buliedian
  • 浏览: 1224423 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

jsp 自定义标签

 
阅读更多

ps:这篇文章是我在javaeye上看到的一篇,写jsp自定义标签的文章,写的比好,所以转贴,共享下!

一、JSP自定义标签简介
标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持多种语言版本。由于标签是XML元素,所以它的名称和属性都是大小写敏感的
标准JSP标签是用来调用JavaBean组件的操作,处理定向请求以简化JSP页面开发与维护。JSP技术提供了一种封装其它动态类型的机制——自定义标签,它扩展了JSP语言。自定义标签通常发布在标签库中,该库定义了一个自定义标签集并包含实现标签的对象。
自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时被转化为servlet,标签转化为对称为tag handler的对象的操作。接着当servlet执行时Web container调用那些操作。

二、两种标签
可以定义两种类型的标签:
javax.servlet.jsp.tagext.Tag
javax.servlet.jsp.tagext.BodyTag

有标签体的标签必须实现 BodyTag 接口。

Html代码
  1. <jsptag:mapscope=“session”name=“tagMap”>
  2. body
  3. </jsptag:map>


也可能没有标签体:

Html代码
  1. <jsptag:map/>

无标签体的简单标签可以实现 Tag 接口。

三、标签处理程序
int doStartTag() throws JspException---处理开始标签
int doEndTag() throws JspException---处理结束标签
Tag getParent()/void setParent(Tag t)---获得/设置标签的父标签
void setPageContext(PageContext pc)--- pageContext 属性的 setter 方法
void release() 释放获得的所有资源

doStartTag()和doEndTag()方法的返回值说明:
SKIP_BODY表示不用处理标签体,直接调用doEndTag()方法。
SKIP_PAGE忽略标签后面的jsp(SUN企业级应用的首选)内容。
EVAL_PAGE处理标签后,继续处理jsp(SUN企业级应用的首选)后面的内容。
EVAL_BODY_BUFFERED表示需要处理标签体,且需要重新创建一个缓冲(调用setBodyContent方法)。
EVAL_BODY_INCLUDE表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
EVAL_BODY_AGAIN 对标签体循环处理。(存在于javax.servlet.jsp.tagext.IterationTag接口中)

实现javax.servlet.jsp.tagext.Tag接口
扩展javax.servlet.jsp.tagext.TagSupport类
TagSupport 类定义了 get/setParent() 和 setPageContext(),这与所有标签处理程序几乎相同。
get/setParent() 方法允许标签嵌套。
TagSupport 类还定义了一个可以被子类使用的 pageContext 实例变量 (protected PageContext pageContext),这个变量是由 setPageContext() 方法设置的。

在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象。在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对。通过在 Web 部署描述符中声明库导入它,然后用指令 taglib 将它导入 JSP 页。

Html代码
  1. <%@tagliburi="firstTag"prefix="my"%>

如果 JSP 容器在转换时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor) (TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一样。

在运行时,JSP 页生成的 servlet 得到对应于这一页面所使用的标签的标签处理程序的一个实例。生成的 servlet 用传递给它的属性初始化标签处理程序。
标签处理程序实现了 生存周期 方法。生成的 servlet 用这些方法通知标签处理程序应当启动、停止或者重复自定义标签操作。生成的 servlet 调用这些生存周期方法执行标签的功能。

四、TLD 文件
TLD 文件的根元素是 taglib。taglib 描述了一个 标签库 —— 即一组标签/标签处理程序对。
因为我们使用的是 JSP 版本 1.2,所以在这个例子中需要 tlib-version 和 short-name 元素。
tlib-version 元素对应于标签库版本。
jsp-version 对应于标签库所依赖的 JSP 技术的版本。
short-name 元素定义了 IDE 和其他开发工具可以使用的标签库的简单名。
taglib 元素包含许多 tag 元素,标签库中每一个标签有一个 tag 元素。

五、编写自定义迭代标签和el表达式调用类的静态方法实例

循环标签体类:ForEach.java

Java代码
  1. importjava.util.Collection;
  2. importjava.util.Iterator;
  3. importjavax.servlet.jsp.JspException;
  4. importjavax.servlet.jsp.tagext.BodyContent;
  5. importjavax.servlet.jsp.tagext.BodyTagSupport;
  6. publicclassForEachextendsBodyTagSupport
  7. {
  8. privateStringid;
  9. privateStringcollection;
  10. privateIteratoriter;
  11. publicvoidsetCollection(Stringcollection)
  12. {
  13. this.collection=collection;
  14. }
  15. publicvoidsetId(Stringid)
  16. {
  17. this.id=id;
  18. }
  19. //遇到开始标签执行
  20. publicintdoStartTag()throwsJspException
  21. {
  22. Collectioncoll=(Collection)pageContext.findAttribute(collection);
  23. //表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
  24. if(coll==null||coll.isEmpty())returnSKIP_BODY;
  25. iter=coll.iterator();
  26. pageContext.setAttribute(id,iter.next());
  27. //表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
  28. //这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
  29. returnEVAL_BODY_INCLUDE;
  30. }
  31. //在doInitBody方法之前执行,在这里被绕过不执行
  32. @Override
  33. publicvoidsetBodyContent(BodyContentarg0)
  34. {
  35. System.out.println("setBodyContent...");
  36. super.setBodyContent(arg0);
  37. }
  38. //此方法被绕过不会被执行
  39. @Override
  40. publicvoiddoInitBody()throwsJspException
  41. {
  42. System.out.println("doInitBody...");
  43. super.doInitBody();
  44. }
  45. //遇到标签体执行
  46. publicintdoAfterBody()throwsJspException
  47. {
  48. if(iter.hasNext())
  49. {
  50. pageContext.setAttribute(id,iter.next());
  51. returnEVAL_BODY_AGAIN;//如果集合中还有对像,则循环执行标签体
  52. }
  53. returnSKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
  54. }
  55. //遇到结束标签执行
  56. publicintdoEndTag()throwsJspException
  57. {
  58. System.out.println("doEndTag...");
  59. returnEVAL_PAGE;
  60. }
  61. }

获取VO属性类:GetProperty.java

Java代码
  1. importjava.lang.reflect.Method;
  2. importjavax.servlet.jsp.JspException;
  3. importjavax.servlet.jsp.tagext.BodyTagSupport;
  4. publicclassGetPropertyextendsBodyTagSupport
  5. {
  6. privateStringname;
  7. privateStringproperty;
  8. publicvoidsetName(Stringname)
  9. {
  10. this.name=name;
  11. }
  12. publicvoidsetProperty(Stringproperty)
  13. {
  14. this.property=property;
  15. }
  16. @SuppressWarnings("unchecked")
  17. publicintdoStartTag()throwsJspException
  18. {
  19. try
  20. {
  21. Objectobj=pageContext.findAttribute(name);
  22. if(obj==null)returnSKIP_BODY;
  23. Classc=obj.getClass();
  24. //构造GET方法名字get+属性名(属性名第一个字母大写)
  25. StringgetMethodName="get"+property.substring(0,1).toUpperCase()
  26. +property.substring(1,property.length());
  27. MethodgetMethod=c.getMethod(getMethodName,newClass[]{});
  28. pageContext.getOut().print(getMethod.invoke(obj));
  29. System.out.print(property+":"+getMethod.invoke(obj)+"/t");
  30. }catch(Exceptione)
  31. {
  32. e.printStackTrace();
  33. }
  34. returnSKIP_BODY;
  35. }
  36. publicintdoEndTag()throwsJspException
  37. {
  38. returnEVAL_PAGE;
  39. }
  40. }

表达式直接访问此类中静态的方法:ELFunction.java

Java代码
  1. publicclassELFunction
  2. {
  3. publicstaticintadd(inti,intj)
  4. {
  5. returni+j;
  6. }
  7. }

写一个测试用的VO类:UserVo.java

Java代码
  1. publicclassUserVo
  2. {
  3. privateStringname;
  4. privateStringpassword;
  5. publicStringgetName()
  6. {
  7. returnname;
  8. }
  9. publicvoidsetName(Stringname)
  10. {
  11. this.name=name;
  12. }
  13. publicStringgetPassword()
  14. {
  15. returnpassword;
  16. }
  17. publicvoidsetPassword(Stringpassword)
  18. {
  19. this.password=password;
  20. }
  21. }

建好TLD文件tag.tld,放在WEB-INF目录下

Xml代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <taglibversion="2.0"
  3. xmlns="http://java.sun.com/xml/ns/j2ee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee
  6. http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  7. <description>自定义标签</description>
  8. <display-name>JSTLcore</display-name>
  9. <tlib-version>1.1</tlib-version>
  10. <short-name>firstLabel</short-name>
  11. <uri>http://java.sun.com/jsp/jstl/core</uri>
  12. <!--创建自定义迭代标签-->
  13. <tag>
  14. <name>forEach</name>
  15. <tag-class>exercise.taglib.ForEach</tag-class>
  16. <!--如果没有标签体,设置empty,如果有标签休必须设置JSP-->
  17. <body-content>JSP</body-content>
  18. <attribute>
  19. <name>id</name>
  20. <required>true</required><!--标识属性是否是必须的-->
  21. <rtexprvalue>true</rtexprvalue><!--标识属性值是否可以用表达式语言-->
  22. </attribute>
  23. <attribute>
  24. <name>collection</name>
  25. <required>true</required>
  26. <rtexprvalue>true</rtexprvalue>
  27. </attribute>
  28. </tag>
  29. <!--创建自定义获得属性标签-->
  30. <tag>
  31. <name>getProperty</name>
  32. <tag-class>exercise.taglib.GetProperty</tag-class>
  33. <body-content>empty</body-content>
  34. <attribute>
  35. <name>name</name>
  36. <required>true</required>
  37. <rtexprvalue>true</rtexprvalue>
  38. </attribute>
  39. <attribute>
  40. <name>property</name>
  41. <required>true</required>
  42. <rtexprvalue>true</rtexprvalue>
  43. </attribute>
  44. </tag>
  45. <!--配置一个表达式调用的函数-->
  46. <function>
  47. <name>add</name><!--配置一个标签,在JSP页面通过引用前缀调用-->
  48. <function-class>exercise.taglib.ELFunction</function-class><!--实现类-->
  49. <function-signature>intadd(int,int)</function-signature><!--静态的方法:包括返回类型,方法名,入参的类型-->
  50. </function>
  51. </taglib>

在web.xml文件中配置自定义标签

Xml代码
  1. <jsp-config>
  2. <taglib>
  3. <taglib-uri>firstTag</taglib-uri>
  4. <taglib-location>/WEB-INF/tag.tld</taglib-location>
  5. </taglib>
  6. </jsp-config>

在jsp文件中使用标签:tag.jsp

Java代码
  1. <%@pagelanguage="java"import="java.util.*"pageEncoding="utf-8"%>
  2. <%@tagliburi="firstTag"prefix="my"%>
  3. <jsp:useBeanid="userVo1"class="exercise.vo.UserVo"scope="request">
  4. <jsp:setPropertyname="userVo1"property="name"value="Hackiller"/>
  5. <jsp:setPropertyname="userVo1"property="password"value="123"/>
  6. </jsp:useBean>
  7. <jsp:useBeanid="userVo2"class="exercise.vo.UserVo"scope="request">
  8. <jsp:setPropertyname="userVo2"property="name"value="YangYang"/>
  9. <jsp:setPropertyname="userVo2"property="password"value="456"/>
  10. </jsp:useBean>
  11. <%
  12. Listlist=newArrayList();
  13. list.add(userVo1);
  14. list.add(userVo2);
  15. pageContext.setAttribute("voList",list);
  16. %>
  17. <html>
  18. <head>
  19. <title>MyJSP'tag.jsp'startingpage</title>
  20. </head>
  21. <body>
  22. <h2align="center">ThisismyJSPpage:测试taglib.</h2>
  23. <hr>
  24. <h2>自定义迭代标签:</h2>
  25. <table>
  26. <tr><td>姓名</td><td>密码</td></tr>
  27. <my:forEachcollection="voList"id="uservo">
  28. <tr>
  29. <td><my:getPropertyname="uservo"property="name"/></td>
  30. <td><my:getPropertyname="uservo"property="password"/></td>
  31. </tr>
  32. </my:forEach>
  33. </table>
  34. <hr>
  35. <h2>表达式调用类的静态方法:</h2>
  36. 2+5=${my:add(2,5)}
  37. </body>
  38. </html>

分享到:
评论

相关推荐

    JSP自定义标签JSP自定义标签

    综上所述,JSP自定义标签提供了一种强大的机制,使得JSP开发者能够创建定制的、可重用的代码片段,提升Web应用的开发效率和质量。通过理解和熟练运用自定义标签,开发者可以更好地组织和管理JSP项目,实现更高效的...

    jsp 自定义标签的使用

    本教程将深入探讨JSP自定义标签的使用,同时结合实例介绍分页和下拉框绑定值的封装。 一、JSP自定义标签基础 1. **定义标签库(Tag Library)**:自定义标签首先需要定义一个TLD(Tag Library Descriptor)文件,它...

    jsp 自定义标签实例

    本实例将深入探讨如何实现一个简单的JSP自定义标签。 首先,自定义标签的实现主要依赖于两个核心概念:Tag接口和TagSupport类。`Tag`接口定义了自定义标签必须实现的方法,如`doStartTag()`和`doEndTag()`,它们...

    jsp自定义标签例子,能在Tomcat下直接运行

    在JSP自定义标签的例子中,我们可以看到这个压缩包文件可能包含了一个完整的示例项目,可以在Apache Tomcat这样的Servlet容器下直接运行。Apache Tomcat是一款开源的Servlet容器,广泛用于部署和运行Java Web应用...

    JSP自定义标签学习笔记

    本篇学习笔记将深入探讨JSP自定义标签的相关概念、创建方法以及实际应用。 一、概述 1.1 使用简单标签机制 JSP自定义标签提供了类似HTML标签的语法结构,通过自定义标签,开发者可以封装复杂的Java代码,使得页面...

    jsp自定义标签报错的问题

    在使用JSP自定义标签时,开发者可能会遇到一些报错问题,这通常涉及到项目结构、类路径设置或自定义标签的编译与打包方式。在本文中,我们将深入探讨这些问题,以及如何解决“JspException”这个特定异常。 首先,...

    jsp自定义标签库实现数据列表显示

    本文将详细讲解如何利用JSP自定义标签库实现数据列表的显示,以及涉及到的相关技术。 首先,`UserListTag.java` 是自定义标签的核心类,它继承了`javax.servlet.jsp.tagext.TagSupport` 或 `javax.servlet.jsp....

    JSP自定义标签之自动完成框

    首先,我们要理解JSP自定义标签的概念。自定义标签是JSP的一种扩展机制,它允许开发者创建自己的标签库,以更加清晰和可维护的方式编写页面。自定义标签的实现通常涉及三个主要部分:标签库描述符(TLD)、标签处理...

    JSP自定义标签之日期显示

    本篇将深入探讨“JSP自定义标签之日期显示”,以及如何通过自定义标签来优雅地处理日期格式化和展示。 首先,我们要理解JSP自定义标签的基本概念。自定义标签是JSP的一种扩展,它不是Java内置的标签,而是由开发者...

    权威实用jsp自定义标签demo<select,checkbox,radio>

    综上所述,“权威实用jsp自定义标签demo,checkbox,radio&gt;”教程旨在帮助开发者掌握如何创建和使用与选择器相关的自定义标签,从而提升JSP开发的效率和质量。通过学习这个教程,你可以了解到自定义标签的核心概念、...

    jsp自定义标签编写的分页

    本教程将深入探讨如何利用JSP自定义标签来编写一个灵活、可扩展的分页系统,该系统不依赖于特定的数据库,具有很高的通用性。 首先,理解JSP自定义标签的工作原理至关重要。自定义标签由三部分组成:标签库描述符...

    jsp自定义标签jsp自定义标签jsp自定义标签

    jsp自定义标签jsp自定义标签jsp自定义标签

    jsp自定义标签库注意事项

    【jsp自定义标签库注意事项】 在Java服务器页面(JSP)开发中,自定义标签库是一种强大的工具,它能够帮助开发者创建可重用的代码片段,提高代码的可读性和可维护性。以下是对JSP自定义标签库的详细解释和使用注意...

    jsp权限控制,jsp自定义标签实现

    使用jsp自定义标签的功能实现权限的控制。(如果用户没有某个模块的删除权限,就不现实这个删除按钮) 在整个项目中所有的页面都可以引入自定义的标签去做到权限的控制。 自定义标签文件 删除 可以控制页面中的每...

Global site tag (gtag.js) - Google Analytics