`
hackiller
  • 浏览: 18461 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

J2EE复习(六)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 接口。

<jsptag:map scope=“session” name=“tagMap”>
  body
</jsptag:map>

 
也可能没有标签体:

<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 页。

<%@ taglib uri="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

import java.util.Collection;
import java.util.Iterator;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class ForEach  extends BodyTagSupport
{
  private String id;
  private String collection;
  private Iterator iter;
  
  public void setCollection(String collection)
  {
    this.collection = collection;
  }
  public void setId(String id)
  {
    this.id = id;
  }
  
  //遇到开始标签执行
  public int doStartTag() throws JspException
  {
    Collection coll = (Collection) pageContext.findAttribute(collection);
    // 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。
    if(coll==null||coll.isEmpty()) return SKIP_BODY;
    
    iter = coll.iterator();
    pageContext.setAttribute(id, iter.next());
    // 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法
    // 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示
    return EVAL_BODY_INCLUDE;
  }
  
  //在doInitBody方法之前执行,在这里被绕过不执行
  @Override
  public void setBodyContent(BodyContent arg0)
  {
    System.out.println("setBodyContent...");
    super.setBodyContent(arg0);
  }
  //此方法被绕过不会被执行
  @Override
  public void doInitBody() throws JspException
  {
    System.out.println("doInitBody...");
    super.doInitBody();
  }
  
  //遇到标签体执行
  public int doAfterBody() throws JspException
  {
    if(iter.hasNext()) 
    {
      pageContext.setAttribute(id, iter.next());
      return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体
    }
    return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。
  }
  
  //遇到结束标签执行
  public int doEndTag() throws JspException
  {
    System.out.println("doEndTag...");
    return EVAL_PAGE;
  }

}

 获取VO属性类:GetProperty.java

import java.lang.reflect.Method;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class GetProperty extends BodyTagSupport
{

  private String name;
  private String property;

  public void setName(String name)
  {
    this.name = name;
  }

  public void setProperty(String property)
  {
    this.property = property;
  }

  @SuppressWarnings("unchecked")
  public int doStartTag() throws JspException
  {
    try
    {
      Object obj = pageContext.findAttribute(name);
      
      if (obj == null) return SKIP_BODY;
      
      Class c = obj.getClass();
      //构造GET方法名字 get+属性名(属性名第一个字母大写)
      String getMethodName = "get" + property.substring(0, 1).toUpperCase() 
                              + property.substring(1, property.length());
      Method getMethod = c.getMethod(getMethodName, new Class[]{});
      
      pageContext.getOut().print(getMethod.invoke(obj));
      System.out.print(property + ":" + getMethod.invoke(obj) + "\t");
    } catch (Exception e)
    {
      e.printStackTrace();
    }
    return SKIP_BODY;
  }

  public int doEndTag() throws JspException
  {
    return EVAL_PAGE;
  }
}

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

public class ELFunction 
{
 public static int add( int i,int j )
 {
  return i+j;
 }
}

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

public class UserVo
{
  private String name;
  private String password;
  
  public String getName()
  {
    return name;
  }
  public void setName(String name)
  {
    this.name = name;
  }
  public String getPassword()
  {
    return password;
  }
  public void setPassword(String password)
  {
    this.password = password;
  }
} 

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

<?xml version="1.0" encoding="utf-8"?>
<taglib version="2.0"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:shcemalocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 <description>自定义标签</description>
 <display-name>JSTL core</display-name>
 <tlib-version>1.1</tlib-version>
 <short-name>firstLabel</short-name>
 <uri>http://java.sun.com/jsp/jstl/core</uri>
 
 <!-- 创建自定义 迭代标签 -->
 <tag>
  <name>forEach</name>
  <tag-class>exercise.taglib.ForEach</tag-class>
  <!-- 如果没有标签体,设置empty , 如果有标签休必须设置JSP-->
  <body-content>JSP</body-content>
  <attribute>
   <name>id</name>
   <required>true</required><!-- 标识属性是否是必须的 -->
   <rtexprvalue>true</rtexprvalue><!-- 标识属性值是否可以用表达式语言 -->
  </attribute>
  <attribute>
   <name>collection</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
 </tag>
 
 <!-- 创建自定义获得属性标签 -->
 <tag>
  <name>getProperty</name>
  <tag-class>exercise.taglib.GetProperty</tag-class>
  <body-content>empty</body-content>
  <attribute>
   <name>name</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <name>property</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
 </tag>
 
 <!-- 配置一个表达式调用 的函数 -->
    <function>
     <name>add</name><!-- 配置一个标签,在JSP页面通过引用前缀调用 -->
     <function-class>exercise.taglib.ELFunction</function-class><!-- 实现类 -->
     <function-signature>int add(int,int)</function-signature><!-- 静态的方法:包括返回类型,方法名,入参的类型 -->
    </function>
</taglib>

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

<jsp-config>
 <taglib>
  <taglib-uri>firstTag</taglib-uri>
  <taglib-location>/WEB-INF/tag.tld</taglib-location>
 </taglib>
</jsp-config>

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

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="firstTag" prefix="my"%>

<jsp:useBean id="userVo1" class="exercise.vo.UserVo" scope="request">
  <jsp:setProperty name="userVo1" property="name" value="Hackiller"/>
  <jsp:setProperty name="userVo1" property="password" value="123"/>
</jsp:useBean>

<jsp:useBean id="userVo2" class="exercise.vo.UserVo" scope="request">
  <jsp:setProperty name="userVo2" property="name" value="YangYang"/>
  <jsp:setProperty name="userVo2" property="password" value="456"/>
</jsp:useBean>

<%
 List list = new ArrayList();
 list.add(userVo1);
 list.add(userVo2);
 pageContext.setAttribute("voList",list);
%>

<html>
  <head>
    <title>My JSP 'tag.jsp' starting page</title>
  </head>
  
  <body>
    <h2 align="center">This is my JSP page:测试taglib.</h2> 
    <hr>
    
   <h2>自定义迭代标签:</h2>
    <table>
     <tr><td>姓名</td><td>密码</td></tr>
     <my:forEach collection="voList" id="uservo">
      <tr>
       <td><my:getProperty name="uservo" property="name"/></td>
       <td><my:getProperty name="uservo" property="password"/></td>
      </tr>
     </my:forEach>
    </table>
    <hr>
    
    <h2>表达式调用类的静态方法:</h2>
    2+5=${my:add(2,5)} 
  </body>
</html>

 

分享到:
评论
1 楼 madbluesky 2009-06-17  
蛮详细的。。。。。

相关推荐

    JSP自定义标签(封装<select>标签)

    JSP自定义标签,封装标签,有两个属性,第一个属性是SQL select语句,只要语法准确,查询出来的数据就会自动加载到select标签,否则无法加载;第二个属性是标签的名称.绝对实用

    J2EE复习(final).

    J2EE复习(final).这是上海的考题,深圳的童鞋们可以参考一下啊。

    J2EE复习提纲

    J2EE复习提纲,为软件工程专业的同学提供。

    j2ee翻页自定义标签+sturts

    这个例子采用了自定义标签翻页和使用sturts中的标签翻页进行了对比使用的是Oracle中的emp表

    j2ee复习资料

    j2ee的复习资料 可以供大家来学习

    韩顺平 j2ee视频实战教程》servlet + jsp的视频

    韩顺平 J2EE视频实战教程JSP详细目录: 韩顺平.j2ee视频实战教程jsp第1讲(上集) 韩顺平.j2ee视频实战教程jsp第1讲(下集) 韩顺平.j2ee视频实战教程jsp第2讲(上集) 韩顺平.j2ee视频实战教程jsp第2讲(中集) 韩顺平.j2ee...

    J2EE认证考试复习资料

    J2EE认证考试复习资料J2EE认证考试复习资料J2EE认证考试复习资料J2EE认证考试复习资料J2EE认证考试复习资料

    J2EE考试复习材料

    J2EE考试复习材料,了解一下,如果你准备考这门课的话。

    J2EE实现通讯录 jsp 基于MYSQL数据库

    J2EE实现通讯录 jsp J2EE实现通讯录 jsp

    J2EE复习资料

    j2ee的复习资料额,走过路过不要错过了,保你考试必过,谢谢

    FlexModule_j2ee Flex 与JSP 整合用的.jar 文件

    FlexModule_j2ee Flex 与JSP 整合用的.jar 文件 Jsp 中引用Flex 标签

    J2EE认证考试复习资料第二版

    J2EE认证考试复习资料第二版J2EE认证考试复习资料第二版J2EE认证考试复习资料第二版J2EE认证考试复习资料第二版J2EE认证考试复习资料第二版J2EE认证考试复习资料第二版

    J2EE期末复习资料

    名词解释:(1)RMI (2)EJB (3)MVC (4)XML (5) J2EE(6)Web Services(7) Spring (8) Java Bean JSP, J2EE,EJB 概念 关系数据库和SQL

    j2ee复习资料j2ee试卷

    j2ee复习资料1、Java2平台的3个版本 2、J2EE的概念 3、J2EE的4层模型图及其说明 4、J2EE构建在J2SE之上吗? 5、Tomcat与Jboss的区别? 6、常见的J2EE服务器有哪些? 7、Eclipse与MyEclipse的关系?

    j2ee期末复习资料

    j2ee复习资料 一、选择题 1.page 指令的(b )属性用于引用需要的包或类 A. extends B.import C. isErrorPage D. language 2.下列选项中,(b ) 可以准确地获取请求页面的一个文本框的输入 (文本框的名称为 name...

    doc\j2ee复习提纲(最新完整版).doc

    \j2ee复习提纲(最新完整版).doc\j2ee复习提纲(最新完整版).doc\j2ee复习提纲(最新完整版).doc\j2ee复习提纲(最新完整版).doc\j2ee复习提纲(最新完整版).doc\j2ee复习提纲(最新完整版).doc\j2ee复习提纲...

    JSP常用自定义标签集feilong-taglib.zip

    feilong-taglib,是 JSP常用自定义标签集 主要由两部分组成 Common 包含所有自定义标签的base类,以及常用的自定义标签 和el function  taglib  说明 isContains  判断一个值,...

    J2EE模式,jsp

    J2EE模式,J2EE,JSP,介绍J2EE模式

    J2EE复习包.zip

    大工软院J2EE,看完必过!!!大连理工大学软件学院,最强复习资料,各种真题,笔记,学长的笔记,倾心复习,往年的J2EE考题,看完J2EE必过!!!

    J2EE JSP 购物车 源代码

    J2EE JSP SERVLET 网上商城 购物车 源代码,J2EE JSP SERVLET 网上商城 购物车 源代码,J2EE JSP SERVLET 网上商城 购物车 源代码,J2EE JSP SERVLET 网上商城 购物车 源代码,J2EE JSP SERVLET 网上商城 购物车 源...

Global site tag (gtag.js) - Google Analytics