简单标签的使用

由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:
setJspContext方法
setParent和getParent方法
setJspBody方法
doTag方法

setJspContext方法
用于把JSP页面的pageContext对象传递给标签处理器对象
setParent方法
用于把父标签处理器对象传递给当前标签处理器对象
getParent方法
用于获得当前标签的父标签处理器对象
setJspBody方法
用于把代表标签体的JspFragment对象传递给标签处理器对象
doTag方法
用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

SimpleTag接口方法的执行顺序:
当web容器开始执行标签时,会调用如下方法完成标签的初始化
  WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
  WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
  如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值, 然后把值传递给标签处理器对象。
  如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。

执行标签时:
容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

1:控制jsp页面某一部分内容是否执行。

public class TagDemo1 extends SimpleTagSupport{

	@Override
	public void doTag() throws JspException, IOException {
		JspFragment jf = this.getJspBody();
		jf.invoke(this.getJspContext().getOut());
	}
	//如果控制不执行的话,直接不写什么就行了
	
}

  <tag>
        <name>demo1</name>
        <tag-class>cn.gbx.web.simpletag.TagDemo1</tag-class>
        <body-content>scriptless</body-content>
    </tag>

  

2:控制整个jsp页面是否执行。

public class TagDemo4 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		throw new SkipPageException();
	}
}

    <tag>
        <name>demo4</name>
        <tag-class>cn.gbx.web.simpletag.TagDemo4</tag-class>
        <body-content>empty</body-content>
    </tag>   

  

3:控制jsp页面内容重复执行。

public class TagDemo2 extends SimpleTagSupport {

	@Override
	public void doTag() throws JspException, IOException {
		JspFragment jf = this.getJspBody();
		for (int i = 0; i < 5; ++i) {
			jf.invoke(null);
		}
	}
	
}

    <tag>
        <name>demo2</name>
        <tag-class>cn.gbx.web.simpletag.TagDemo2</tag-class>
        <body-content>scriptless</body-content>
    </tag>

  

4:修改jsp页面内容输出。

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().toUpperCase();
		 this.getJspContext().getOut().write(content);
	}

}

    <tag>
        <name>demo3</name>
        <tag-class>cn.gbx.web.simpletag.TagDemo3</tag-class>
        <body-content>scriptless</body-content>
    </tag>

  

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最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。

原文地址:https://www.cnblogs.com/E-star/p/3554462.html