`
hackiller
  • 浏览: 18980 次
  • 性别: 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  
蛮详细的。。。。。

相关推荐

    J2EE复习题和答案完美版

    知识点:JSP自定义标签。自定义标签需要实现Tag接口,其中包括doStartTag()、doEndTag()、doInitBody()、doAfterBody()等方法。在这里,遇到结束标签时将调用doEndTag()方法,因此正确答案是b) doEndTag()。 4. 在...

    jsp期末复习资料总结

    JSP标记分为指令标记(如%@ page属性%&gt;)、动作标记(如&lt;jsp:include&gt;)和自定义标记(自定义的JSP标签库)。 以上内容涵盖了JSP的基础知识,包括其原理、配置、页面结构、工作流程以及常用元素和对象。这些知识点...

    JSP程序设计考试复习.pdf

    最后,JSP页面可以使用JSP标签库中的自定义标签来实现更复杂的操作,比如数据分页、数据验证等。自定义标签通常定义在.tld文件中,并通过 &lt;%@ taglib %&gt; 指令引入。 在JSP页面中,还可以使用JavaBean来封装业务逻辑...

    JSP期末考试题复习题.docx

    3. 自定义标签处理:当JSP页面执行自定义标签遇到结束标签时,会调用`doEndTag()`方法执行处理。因此,正确答案是b)doEndTag()。 4. JSP作用域:要使user对象在整个对话中一直存在,直至其终止或被删除,应该...

    j2ee作业练习五答案

    JSP的转换过程、EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)的使用、以及自定义标签可能都是练习的重要内容。 3. **JavaBeans**:JavaBeans是一种符合特定设计模式的Java类,通常...

    黄淮学院J2EE考试复习试题

    ### 黄淮学院J2EE考试复习知识点解析 #### Struts2框架的发展历程与核心功能 1. **Struts2框架的起源与发展** Struts2框架是由`webWork`和`xWork`框架发展而来的。其中,`XWork`是一个标准的Command模式实现,...

    JSP复习试题

    1. **自定义标签配置**:自定义标签的配置文件通常存放在`WEB-INF`目录下,以便保护不受客户端直接访问。因此,正确答案是D。 2. **重定向**:在J2EE中,用于重定向到另一个页面的正确语句是使用`response....

    JSP期末考试题复习题[001].pdf

    3)当JSP页面执行自定义标签,遇到结束标签时将调用`doEndTag()`方法执行处理。这是自定义标签生命周期的一部分,`doEndTag()`在标签结束时执行。 4)在J2EE中,若要使user对象一直存在于对话中,直至其终止或被...

    J2EE考试复习试题-struts2-spring-hibernate(答案整合完毕).doc

    ### J2EE考试复习知识点详解 #### 一、Struts 2 框架概述 1. **Struts 2框架的发展历程**: - **起源**:Struts 2框架是由`webWork`和`xWork`两个框架发展而来的。 - **XWork框架**:它是一个通用的Command模式...

    niit J2EE在线考试

    2. **JSP**:掌握JSP页面的结构,会用EL和JSTL,理解自定义标签的使用。 3. **EJB(Enterprise JavaBeans)**:学习实体Bean(Entity Beans)、会话Bean(Session Beans)和消息驱动Bean(Message-Driven Beans),...

    师大 - jsp考试题

    【JSP(Java Server ...通过这三份文档,学习者可以系统地复习JSP和J2EE的相关知识,为考试或项目开发做好充分准备。无论是对初学者还是有经验的开发者,深入理解和熟练运用JSP都是提高Java Web开发能力的关键步骤。

    Java Web期末复习题含答案.docx

    6. **自定义标签**:自定义标签的主要作用是分离JSP中的Java代码,简化前端开发,提高代码可读性。 7. **RequestDispatcher.forward()**:这个方法用于在服务器端进行转发操作,请求和响应不会离开服务器。 8. **...

    J2 EE 练习题

    自定义标签的描述文件(TLD文件)在web.xml中的配置应使用`&lt;jsp-config&gt;&lt;taglib&gt;`元素,并设置`taglib-uri`和`taglib-location`属性,分别指定自定义标签库的URI和实际位置。 以上知识点全面覆盖了J2EE中的一些核心...

    J2EE考试复习试题_struts2_spring_hibernate(答案整合完毕

    为了在JSP页面中运用Struts2的标签库,必须通过taglib指令导入,例如: ```html ``` 此指令将Struts2标签库添加到当前页面,使得开发者可以方便地使用诸如等表单标签。 #### 三、Hibernate数据持久化技术 ...

    310-081认证考试学习资料

    - 学习如何创建自定义标签库,以及如何使用这些标签来简化JSP页面的开发过程。 - 了解如何实现`SimpleTag`接口以创建简单的自定义标签。 - 掌握如何处理自定义标签中的属性和体内容。 #### 4. **过滤器(Filter)与...

    系统分析员考试复习资料

    - JSP可以通过JavaServer Pages Standard Tag Library (JSTL) 和自定义标签库简化逻辑处理。 4. **企业计算的基本服务**: - 8种基本服务包括命名/目录服务、数据访问服务、分布式对象服务、企业管理服务、事务...

    系统分析师考试复习资料

    系统分析师考试复习资料涵盖多个IT领域的知识点,主要集中在JavaBean、Enterprise JavaBean(EJB)、JSP、J2EE框架以及远程方法调用(RMI)和XML等核心技术上。以下是对这些知识点的详细说明: 1. **JavaBean组件...

    刘晓涛J2EE教程之Java面试题分析

    9. **J2EE相关**:既然标题提到J2EE,那么Servlet、JSP、MVC模式、Spring框架、Hibernate ORM等Web开发技术也可能会被涉及。 10. **数据库知识**:SQL查询、事务管理、索引优化等数据库基础和进阶知识也是面试中常...

    基于J2EE技术的计算机网络实习实训系统设计与实现.pdf

    同时,利用JSP(JavaServer Pages)进行视图展示,Servlet进行业务处理,EJB(Enterprise JavaBeans)处理企业级服务,如数据库连接和事务管理。 数据库设计是系统的关键部分,需要存储网络设备信息、实验配置、...

Global site tag (gtag.js) - Google Analytics