一、简单标签共定义了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. Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...

  5. 学习笔记:CentOS7学习之十九:Linux网络管理技术

    目录 学习笔记:CentOS7学习之十九:Linux网络管理技术 本文用于记录学习体会.心得,兼做笔记使用,方便以后复习总结.内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK ...

  6. 风炫安全WEB安全学习第十九节课 XSS的漏洞基础知识和原理讲解

    风炫安全WEB安全学习第十九节课 XSS的漏洞基础知识和原理讲解 跨站脚本攻击(Cross-site scripting,通常简称为XSS) 反射型XSS原理与演示 交互的数据不会存储在数据库里,一次 ...

  7. python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法

    python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法 同一台机器同时安装 python2.7 和 python3.4不会冲突.安装在不同目录,然 ...

  8. 风炫安全web安全学习第二十九节课 CSRF防御措施

    风炫安全web安全学习第二十九节课 CSRF防御措施 CSRF防御措施 增加token验证 对关键操作增加token验证,token值必须随机,每次都不一样 关于安全的会话管理(SESSION) 不要 ...

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

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

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

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

随机推荐

  1. WP8 学习 Onnavigatedto和OnnavigatedFrom的区别

    OnNavigatedTo:重写 OnNavigatedTo 方法以检查导航请求并且准备供显示的页面.这个方法就像是初始化(Ini) ,它先于Loaded事件之前被执行,所以在这里可以控制一些初始化前 ...

  2. IE9的css hack

    以前写过<IE8的css hack>,ie9一出css hack也该更新,以前一直没关注,今天在内部参考群mxclion分享了IE9的css hack,拿出来也分享一下: select { ...

  3. KING小组

    KING——学习小组 小组成员及github地址&博客地址: 张静 https://github.com/loiskris/test.git  http://www.cnblogs.com/l ...

  4. Xcode6中segue取消原push与modal(deprecated)

    xcode6 之后push 和modal 就被废弃了.只能用于ios8之前.在拖线的时候我们就可以看见. 这两个方法被废弃了,我们需要找到合适的方法来代替,这时候我们发现 show 和Present ...

  5. UINavigationController 子控制器管理原理

    UINavigationController 显示在导航控制器上的控制器 永远是栈顶控制器 后进先出  先进后出原则 /** * 程序获得焦点才能获取触摸事件 * */- (void)applicat ...

  6. C++指针详解

    指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占 ...

  7. 加载JS

  8. 渐进记法(O,Ω,Θ)

    第一次在<算法导论>中看到这三种渐进记法的符号,当时对此一窍不通,所以也就没有注意它们,直接把他们忽略了,知道学习算法的时候,才知道当初的做法有多傻,因为一个算法的好坏以及复杂度,可以用它 ...

  9. Camel routes in Spring config file

    The normal spring bean definition configuration file, the xsi:schemaLocation only has two: beans and ...

  10. 微信公众号 SDK

    <?php /* 方倍工作室 http://www.fangbei.org/ CopyRight 2015 All Rights Reserved */ define("TOKEN&q ...