简单标签的简介和实例运用
一 概念
1.简单标签出现的目的
由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。
2.简单标签定义的方法---SimpleTag接口的方法
(1)setJspContext
用于把jsp页面的pageContex对象传递给标签处理器对象
(2)setParent
用于把父标签处理器对象传递给当前的标签处理器对象
(3)getParent
用于获取当前标签的父标签处理器对象
(4)setJspBody
用于把代码标签体的JspFargment对象攒的给标签处理器对象
(5)doTag
用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等,
3.简单标签的实现接口和实现类的介绍
(1)SimpleTag接口方法的执行顺序
l 当web容器开始执行标签时,会调用如下方法完成标签的初始化
• WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
• WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
• 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
• 如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
l 执行标签时:
• 容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。
(2)JspFragment类
l javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素。
l WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
l getJspContext方法
• 用于返回代表调用页面的JspContext对象.
l public abstract void invoke(java.io.Writer out)
• 用于执行JspFragment对象所代表的JSP代码片段
• 参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
(3)invoke方法详解
l JspFragment.invoke方法可以说是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:
• 在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;
• 在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;
• 若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。
Invoke方法的使用实例:
//setJspBody是系统自动 调用的,得到标签体内容对象
JspFragment jf = this.getJspBody();
//标签体内容的输出
jf.invoke(this.getJspContext().getOut());
//等价于jf.invoke(null);//输出到客户端
二 简单标签的实例---没有增加属性:
1.输出简单标签的内容:
(1)创建一个标签处理器
public void doTag() throws JspException, IOException {
//获取标签体
JspFragment jf = this.getJspBody();
//从浏览器输出
jf.invoke(null);
}
注:如果遇到此标签不执行剩下的内容,则只要抛出异常就OK
throw new SkipPageException();
2.控制页面是否显示
(1) 创建一个标签处理器
public void doTag() throws JspException, IOException {
//抛异常之后就会终止剩下的部分
throw new SkipPageException();
}
注://如果没有标签体会抛空指针异常,所有去掉
//获取标签体
//JspFragment jf = this.getJspBody();
//从浏览器输出
// jf.invoke(null);
(2)tld文件进行描述
<tag>
<name>demo7</name>
<tag-class>com.hbsi.web.tag.SimpleTagDemo7</tag-class>
<body-content>empty</body-content>
</tag>
3.简单标签创建标签体修改内容
标签处理器中的
public void doTag() throws JspException, IOException {
// 得到标签体的对象
JspFragment jf = this.getJspBody();
// 创建缓冲
StringWriter sw = new StringWriter();
// 获取缓冲区内容的标签体对象
jf.invoke(sw);
// 转化成字符串并为大写
String content = sw.toString().toUpperCase();
// 通过获取流对象输出
JspWriter jw = this.getJspContext().getOut();
jw.write(content);
}
三 带属性的标签实例
1.简单标签控制迭代
(1)创建一个标签处理器
//简单标签的属性,和私有属性名称一致
private int count;
public void setCount(int count) {
this.count = count;
}
//迭代的操作
public class SimpleTagDemo8 extends SimpleTagSupport
public void doTag() throws JspException, IOException {
JspFragment jf = this.getJspBody();
for(int i=0;i<count;i++)
jf.invoke(null);
}
(2)部署til文件
<tag>
<name>demo8</name> 标签后名
<tag-class>com.hbsi.web.tag.SimpleTagDemo8</tag-class> 类
<body-content>scriptless</body-content> 类型
<!-- 属性的增加 -->
<attribute>
<name>count</name>
<required>true | false</required> 属性是不是必须的 <!-- 运行时表达式运算 -->
<rtexprvalue>true | false</rtexprvalue>
</attribute>
</tag>
注:(1)运行时表达式运算,比如:
<csdn:demo8 count=”${date}”>
<%=${date+1}%>
(3)在jsp页面的访问
<csdn:demo8 count="15">
This is my JSP page. <br>
</csdn:demo8>
2.给简单标签属性赋值:
(1)如果属性是基本数据类型,如:
count=”8”是字符类型的,当在调用setter方法时,会自动转换为int类型,并且仅限于基本的数据类型
(2)如果不是基本类型的,
在jsp文件中:
<csdn:demo10 date="<%=new java.util.Date()%>"/>
在SimpleTagDemo10的类中
public class SimpleTagDemo10 extends SimpleTagSupport {
private Date date;
public void setDate(Date date) {
this.date = date;
}
public void doTag() throws JspException, IOException {
JspWriter jw =this.getJspContext().getOut();
jw.write(date.toString());
}
注:
(1)要想让一个自定义标签具有属性,通常需要完成两个任务:
在标签处理器中编写每个属性对应的setter方法
在TLD文件中描术标签的属性
(2)为自定义标签定义属性时,每个属性都必须按照JavaBean的属性命名方式,在标签处理器中定义属性名对应的setter方法,用来接收JSP页面调用自定义标签 时传递进来的属性值。 例如属性url,在标签处理器类中就要定义相应的setUrl(String url)方法。
(3)在标签处理器中定义相应的set方法后,JSP引擎在解析执行开始标签前,也就是调用doStartTag方法前,会调用set属性方法,为标签设置属性。
在.tld文件中属性的图示详解:
元素名 |
是否必须指定 |
描 述 |
description |
否 |
用于指定属性的描述信息。 |
name |
是 |
用于指定属性的名称。属性名称是大小写敏感的,并且不能以jsp、_jsp、java和sun开头。 |
required |
否 |
用于指定在JSP页面中调用自定义标签时是否必须设置这个属性。其取值包括true和false,默认值为false,true表示必须设置,否则可以设置也可以不设置该属性。 |
rtexprvalue |
否 |
rtexprvalue是runtime expression value(运行时表达式)的英文简写,用于指定属性值是一个静态值或动态值。其取值包括true和false,默认值为false,false表示只能为该属性指定静态文本值,例如"123";true表示可以为该属性指定一个JSP动态元素,动态元素的结果作为属性值,例如JSP表达式<%=value %>。 |
type |
否 |
用于指定属性值的Java类型。 |