一、简单标签共定义了5个方法:

setJspContext方法
setParent和getParent方法
setJspBody方法
doTag方法
二、方法介绍

osetJspContext方法

用于把JSP页面的pageContext对象传递给标签处理器对象

osetParent方法

用于把父标签处理器对象传递给当前标签处理器对象

ogetParent方法

用于获得当前标签的父标签处理器对象

osetJspBody方法

用于把代表标签体的JspFragment对象传递给标签处理器对象

odoTag方法

用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

三、接口方法的执行顺序

1.当web容器开始执行标签时,会调用如下方法完成标签的初始化
WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
2.执行标签时:
容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。
四、JspFragment类
¨javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素。
¨WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
¨getJspContext方法
用于返回代表调用页面的JspContext对象.
public abstract void invoke(java.io.Writer out)
用于执行JspFragment对象所代表的JSP代码片段
参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
五、invoke方法详解 
¨JspFragment.invoke方法是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
o在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
o在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
o若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。
六、案例分析
  方法分析:
    public class DemoTag1 implements SimpleTag {
    private PageContext pageContext;
    private String name;

/**
     * 用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容。在doTag方法中可以抛出javax.servelt.jsp.
     * SkipPageException异常
     * ,用于通知web容器不再执行JSP页面中位于结束标记后面的内容,者等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况
     * *
     */
    @Override
    public void doTag() throws JspException, IOException {
        System.out.println("doTag");
    }

/**
     * 用于获得当前标签的父标签的处理器对象
     */
    @Override
    public JspTag getParent() {
        System.out.println("getParent");
        return null;
    }

/**
     * 用于吧代表标签体的JspFragment对象传递给标签处理器对象
     */
    @Override
    public void setJspBody(JspFragment jspBody) {
        System.out.println("setJspBody");

}

/**
     * 用于把JSP页面的pageContext对象传递给标签处理器对象
     */
    @Override
    public void setJspContext(JspContext pc) {
        this.pageContext = (PageContext) pc;
        System.out.println("setJspContext");

}
    /**
     * 用于把父标签处理器对象传递给当前标签处理器对象
     */
    @Override
    public void setParent(JspTag parent) {
        System.out.println("setParent");

}

/**
     * 属性是通过这个setter方法设置进来
     */
    public void setName(String name) {
        System.out.println("设置name属性"+name);
        this.name = name;
    }

}

  
  1.//控制标签体是否执行
public class TagDemo1 extends SimpleTagSupport {

@Override
    public void doTag() throws JspException, IOException {
        JspFragment jf = this.getJspBody();
    }
}

页面:
<html>
  <head>    
    <title>控制标签体是否执行</title>
  </head>
 
  <body>
       <hytc:demo1>
           xxxx
       </hytc:demo1>
  </body>
</html>

2.//控制标签体是否执行
public class TagDemo2 extends SimpleTagSupport {

@Override
    public void doTag() throws JspException, IOException {
        JspFragment jf = this.getJspBody();
        for(int i=0;i<10;i++){
            jf.invoke(null);
        }    
    }
}
页面:
<html>
  <head>    
    <title>控制标签体重复执行</title>
  </head>
 
  <body>
       <hytc:demo2>
           xxxx
       </hytc:demo2>
  </body>
</html>
3.//修改标签体
public class TagDemo3 extends SimpleTagSupport {

@Override
    public void doTag() throws JspException, IOException {
        
        JspFragment jf = this.getJspBody();
        StringWriter sw = new StringWriter();
        jf.invoke(sw);
        
        String content = sw.toString();
        content = content.toUpperCase();
        
        this.getJspContext().getOut().write(content);
    }
    
}
页面:
<html>
  <head>    
    <title>修改标签体</title>
  </head>
 
  <body>
       <hytc:demo3>
           xxxx
       </hytc:demo3>
  </body>
</html>

4.//控制整个jsp是否执行
public class TagDemo4 extends SimpleTagSupport {
    @Override
    public void doTag() throws JspException, IOException {
        throw new SkipPageException();
    }
}
页面:
<hytc:demo4/>
<html>
  <head>    
    <title>修改标签体</title>
  </head>
 
  <body>

</body>
</html>
5.//
public class TagDemo5 extends SimpleTagSupport {
    
    private int count;
    private Date date;

public void setCount(int count) {
        this.count = count;
    }
    
    public void setDate(Date date) {
        this.date = date;
    }

@Override
    public void doTag() throws JspException, IOException {
        
        System.out.println(date);
        for(int i=0;i<count;i++){
            this.getJspBody().invoke(null);
        }
    }
}
页面:
<html>
  <head>    
    <title>My JSP '5.jsp' starting page</title>
  </head>
 
  <body>
    
    <hytc:demo5 count="5" date="<%=new Date() %>">
        aaaaaaa
    </hytc:demo5>    
    
  </body>
</html>
6.配置文件:
  <tag>
        <name>demo1</name>
        <tag-class>web_16.simpletag.TagDemo1</tag-class>
        <body-content>scriptless</body-content>
    </tag>
     
    <tag>
        <name>demo2</name>
        <tag-class>web_16.simpletag.TagDemo2</tag-class>
        <body-content>scriptless</body-content>
    </tag>
    
     <tag>
        <name>demo3</name>
        <tag-class>web_16.simpletag.TagDemo3</tag-class>
        <body-content>scriptless</body-content>
    </tag>
    
     <tag>
        <name>demo4</name>
        <tag-class>web_16.simpletag.TagDemo4</tag-class>
        <body-content>scriptless</body-content>
    </tag>
    
     <tag>
        <name>demo5</name>
        <tag-class>web_16.simpletag.TagDemo5</tag-class>
        <body-content>scriptless</body-content>
        
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        
        <attribute>
            <name>date</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
      </tag>

JavaWeb学习记录(十九)——jstl自定义标签之简单标签的更多相关文章

  1. javaweb学习总结(十九)——JSP标签

    一.JSP标签介绍 JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. 二.JSP常用标签 ...

  2. JavaWeb学习记录(九)——Cookie的增加、删除、查看

    一.servlet功能代码: public void doGet(HttpServletRequest request, HttpServletResponse response)           ...

  3. javaweb学习总结十九(http协议概述以及http请求信息分析)

    一:http协议概述 1:http协议定义 2:使用telnet程序连接web服务器,获取资源 3:http协议:超文本传输协议,它是基于tcp/ip协议,就是建立在tcp/ip之上工作的, http ...

  4. 传智播客JavaWeb day07、day08-自定义标签(传统标签和简单标签)、mvc设计模式、用户注册登录注销

    第七天的课程主要是讲了自定义标签.简单介绍了mvc设计模式.然后做了案例 1. 自定义标签 1.1 为什么要有自定义标签 前面所说的EL.JSTL等技术都是为了提高jsp的可读性.可维护性.方便性而取 ...

  5. JavaWeb学习记录(十九)——jstl自定义标签库之传统标签

    一.传统标签 (1)JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法. public void setPageContext(PageCo ...

  6. javaweb学习总结(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

  7. JavaWeb学习记录(二十一)——国际化处理

    ¨国际化又称为 i18n:internationalization ¨对于软件中的菜单栏.导航条.错误提示信息,状态信息等这些固定不变的文本信息,可以把它们写在一个properties文件中,并根据不 ...

  8. 【JAVAWEB学习笔记】18_el&amp;jstl&amp;javaee的开发模式

    一.EL技术 1.EL 表达式概述 EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL 出现的目的是要替代jsp页面中脚本的编写. 2.EL从域中取出数据 ...

  9. JSP自定义标签之简单标签入门

    在sun官方文档上有下面这样一段话. 官方文档声明 public interface SimpleTag extends JspTag Interface for defining Simple Ta ...

随机推荐

  1. Codeforces663E Binary Table(FWT)

    题目 Source http://codeforces.com/contest/663/problem/E Description You are given a table consisting o ...

  2. Shell入门教程:命令替换 $() 和 ``

    所谓命令替换,是把命令执行后的标准输出放入变量中.这是一个十分有威力的功能.例如说, 想查看工作目录中所有的文件名,可执行ls命令,但如何把这些文件名存入变量中,供往后的程序代码再利用呢? 使用命令替 ...

  3. 「Ionic」創建新項目

    1.創建新項目 创建一个名为myApp的还有tabs的项目(ionic start <project-name> <optional-template>) 可选模板为sidem ...

  4. web前端命名规范

    在做web项目的时候,命名的规范是很重要.初学者一般急于求成对命名规范没有概念,觉得花时间这些还不如多看几遍框架.其实在我看来,一个良好的命名习惯是很重要的.下面就来介绍一下我总结的命名规范: (1) ...

  5. git浅谈

    我们为什么要使用git 应用场景分析 1.使用svn,已经开发完一个需求,正在开发第二个需求,但是测试需要你立刻将你完成的第一个需求提交,请问现在你该怎么做: svn的解决方法大概是这样的:打开提交视 ...

  6. 手动启动mongodb和nodejs程序

    最近做单片机去了,以前用的mongodb和nodejs没有配置成服务,居然忘了如何手动启动.在此记录下 一.手动启动mongodb 1.进入cmd 2.在dos下打开mongodb路径E:\mongo ...

  7. 【Java 基础篇】【第二课】基本数组类型

    就像第一章所说一样,这次学习为了快,因此说明性的文字就不想写太多了,直接帖代码吧,代码当中尽量加一些注释: package a.b; public class test { static void B ...

  8. 如何在.NET MVC中使用jQuery并返回JSON数据

    http://blog.csdn.net/dingxingmei/article/details/9092249 开始实践 - jQuery端 假设我们要从服务器端获取一个文章列表,并把文章条目显示在 ...

  9. Apache与Nginx服务器对比

      apache NginX 占用资源和内存 多 轻量级,同样起Web服务,占内存和资源更少   阻塞型 抗并发,异步非阻塞的,高并发下,可保持低资源低消耗低性能   可用的模块超多 可自定义模块,编 ...

  10. Asp.net获取用户真实Ip地址

    /// <summary> /// 获取远程访问用户的Ip地址 /// </summary> /// <returns>返回Ip地址</returns> ...