自定义JSP标签详解------简单标签

简单标签库开发常用功能 ,实现SimpleTag接口标签类 (SimpleTag JSP2.0之后为了简化标签开发提供的 )

** ***  编写简单标签类 只需要继承 SimpleTagSupport 类

实现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常量的情况


Tip:SimpleTag接口方法的执行顺序

当web容器开始执行标签时,会调用如下方法完成标签的初始化
  1. WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
  2. WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
  3. 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
  4. 如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
执行标签时
  1. 容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

Tip:JspFragment类


javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素


对于简单标签,其<tag>元素的<body-content>子元素的可选值包括empty、scriptless和tagdependent,默认值为scriptless。对于传统的自定义标签,<body-content>子元素的可选值包括empty、Jsp、scriptless和tagdependent。由于简单标签的主体不能包含Java程序片段等脚本元素,所以<body-content>子元素的值不能为JSP。




WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:

getJspContext方法

用于返回代表调用页面的JspContext对象. ----pageContext

public abstract void invoke(java.io.Writer out)  -- 输出标签体内容

•用于执行JspFragment对象所代表的JSP代码片段

•参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)


Tip:invoke方法详解  


JspFragment.invoke方法是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。

例如:
  • 在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
  • 在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
  • 若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。

 例一:控制标签体内容是否执行

标签处理类Class:

<span style="font-size:18px;">public class Demo1Tag extends SimpleTagSupport{

	@Override
	public void doTag() throws JspException, IOException {
		//什么都不写就是标签体不执行,因为在执行流程中setJspBody讲标签体写到的缓存中,</span>
<span style="font-size:18px;">                //如果不调用invoke方法标签体就会在缓存中不会显示在页面上。
		//如果想执行标签体,就调用invoke方法
                //getJspBody().invoke(getJspContext().getOut());
		//可以直接简化传递的输出流的参数,如果为NULL,则采用默认的输出流,默认的输出流就是out对象
		getJspBody().invoke(null);
	}
}</span>


描述标签TLD:

<span style="font-size:18px;"><tag>
 	<!-- 标签名称 -->
 	<name>demo1Tag</name>
 	<!-- 标签类 -->
 	<tag-class>com.rxtmedia.foot.text.Demo1Tag</tag-class> 
 	<body-content>scriptless</body-content>
 </tag></span>


例二:控制标签后的jsp页面是否执行

标签处理类class:

public class Demo2Tag extends SimpleTagSupport {
	@Override
	public void doTag() throws JspException, IOException {
		// 什么都不写剩余页面会继续执行
		// 如果不想执行页面后面内容
		throw new SkipPageException();
	}
}

标签描述TLD:

<span style="font-size:18px;"> <tag>
 	<!-- 标签名称 -->
 	<name>demo2Tag</name>
 	<!-- 标签类 -->
 	<tag-class>com.rxtmedia.foot.text.Demo2Tag</tag-class> 
 	<body-content>scriptless</body-content>
 </tag></span>


例三:控制jsp页面内容重复执行

public class Demo3Tag extends SimpleTagSupport{

	@Override
	public void doTag() throws JspException, IOException {
		for(int i = 0 ; i < 10 ; i++){
			// 执行标签体
			getJspBody().invoke(null);
		}
	}
}

描述标签文件TLD:

<span style="font-size:18px;"> <tag>
 	<!-- 标签名称 -->
 	<name>demo3Tag</name>
 	<!-- 标签类 -->
 	<tag-class>com.rxtmedia.foot.text.Demo3Tag</tag-class> 
 	<body-content>scriptless</body-content>
 </tag></span>

例四:修改jsp页面内容输出

标签处理类class:

public class Demo4Tag extends SimpleTagSupport{
	@Override
	public void doTag() throws JspException, IOException {
		// 获得缓存中标签体内容
		StringWriter stringWriter = new StringWriter();
		// 将标签体内容写入stringwriter
		getJspBody().invoke(stringWriter);
		String str = stringWriter.toString();
		str = str.toUpperCase();
		
		// 输出到页面 需要out对象
		JspWriter out = this.getJspContext().getOut();
		out.print(str);
	}

}

描述标签文件TLD:

<span style="font-size:18px;"><tag>
 	<!-- 标签名称 -->
 	<name>demo4Tag</name>
 	<!-- 标签类 -->
 	<tag-class>com.rxtmedia.foot.text.Demo4Tag</tag-class> 
 	<body-content>scriptless</body-content>
 </tag></span>


例五:创建和使用带动态属性的简单标签


标签处理类class:

public class Demo5Tag extends SimpleTagSupport implements DynamicAttributes{

	private ArrayList<String> al = new ArrayList<String>();
	
	@Override
	public void setDynamicAttribute(String uri, String localName, Object value)
			throws JspException {
		al.add((String) value);
	}

	@Override
	public void doTag() throws JspException, IOException {
		int max = 0 ;
		for(int i =0 ; i < al.size() ; i++){
			int num = Integer.parseInt(al.get(i));
			max = num > max ? num : max ;
		}
		System.out.println(max);
		// 将最大的值写到页面
//		context.setAttribute("max",new Integer(max));
	}
} 

标签描述文件TLD:

<span style="color:#336666;"><tag>
 	<!-- 标签名称 -->
 	<name>demo5Tag</name>
 	<!-- 标签类 -->
 	<tag-class>com.rxtmedia.foot.text.Demo5Tag</tag-class> 
 	<body-content>scriptless</body-content>
 	</span><span style="color:#cc0000;"><dynamic-attributes>true</dynamic-attributes></span><span style="color:#336666;">
 </tag></span>






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值