自定义标签
1、使用自定义标签的步骤
1.1、编写对标签行为做出处理的控制类
// javax.servlet.jsp.tagext.SimpleTagSupport;
public class HelloTag extends SimpleTagSupport {
@Override
public void doTag() throws JspException, IOException {
}
}
1.2、在 标签库描述符 文件中的 定义标签
<tag>
<!-- 使用 name 标记声明在标签名称( 就是在页面上使用的标签名称 , 比如 x:hello 中的 hello ) -->
<name>hello</name>
<!-- 指定对标签行为做出处理的控制类-->
<tag-class>cn.itlaobing.HelloTag</tag-class>
<!-- 对于 空标签体 的标签来说,将 body-content 设置为 empty 即可 -->
<body-content>empty</body-content>
</tag>
1.3、在需要使用自定义标签的JSP页面上导入标签库
<%@ taglib prefix="x" uri="http://www.ycpower.xyz/tags" %>
1.4、 使用标签
<x:hello />
2、定义属性:
2.1、在 标记内部使用 可以定义某个标记的属性
<attribute>
<name>width</name>
<!-- 指示将来在页面上使用 block 标签时是否必须指定 width 属性 ( true 表示必须指定,false表示可选 )-->
<required>true</required>
<!-- 指示 width 属性是否允许接受动态值( true 表示允许接受动态值,false表示不允许 ) -->
<rtexprvalue>true</rtexprvalue>
<!-- Runtime Expression Value 表示运行期表达式的值 -->
<type>int</type>
</attribute>
2.2、在标签对应的 处理器类中,同样使用 属性 接受来自页面传递的值
public class BlockTag extends SimpleTagSupport {
private int w ; // 字段 ( Fileld )
private int h ; // 字段 ( Fileld )
private int border ; // 字段 ( Fileld )
private String borderColor ; // 字段 ( Fileld )
public int getWidth() {
return w;
}
// setWidth(int width) ==> 去掉 set 去掉 () 部分 ==> Width ==> 首字母变小写 width ( 属性 (property) )
public void setWidth(int width) {
this.w = width;
}
public int getHeight() {
return h;
}
public void setHeight(int height) {
this.h = height;
}
public int getBorder() {
return border;
}
public void setBorder(int border) {
this.border = border;
}
public String getBordercolor() {
return borderColor;
}
public void setBordercolor(String bordercolor) {
this.borderColor = bordercolor;
}
}
2.3、在页面上的标签中使用属性
<x:block width="400" height="200" border="10" bordercolor="green" />
3、处理标签体
3.1、在 JSP 页面上使用含有标签体的标签
<%@ taglib prefix="x" uri="http://www.ycpower.xyz/tags" %>
<x:for begin="5" end="1" step="1" var="index" >
<div class="first"> ${ index } </div>
</x:for>
3.2、在 标签库描述符 文件中 设置 标签体
<tag>
<name>for</name>
<tag-class>cn.itlaobing.ForTag</tag-class>
<!-- 允许在 for 标签的标签体中使用 JSP 页面上的内容,比如使用 EL表达式 -->
<body-content>scriptless</body-content>
</tag>
对于 body-content 来说,常用的取值是:
empty 表示空标签体
scriptless 表示在标签体中可以出现 HTML和 EL 等内容
3.3、处理标签体
理解 JspFragment
一个 JSP 页面会对应一个Servlet类; ( JSP的本质 )
访问 JSP 页面实质上就是访问相应的 Servlet 类的实例 ;
访问 JSP 页面时所访问的 Servlet 类的实例表示一个 页面 ( page ) 对象 ;
如果要访问 一个 页面( page ) 对象 关联的其它对象,可以通过 页面上下文 ( pageContext ) 对象来实现;
而 pageContext 的类型是 javax.servlet.jsp.PageContext 类,PageContext 类的父类是 javax.servlet.jsp.JspContext 类。
一个 页面 ( page ) 可以分成不同的部分,比如 <x:hello /> 就是 一个页面( page ) 的 一个片段 ( fragment )
一个标签的标签体就是 JSP页面上的的一个片段 ,这个类型就是 javax.servlet.jsp.tagext.JspFragment 类型。
比如,对于:
<x:for begin="5" end="1" step="1" var="index" >
<div class="first"> ${ index } </div>
</x:for>
来说,for 是 x 标签库中的一个标签,而
${ index }
就对应 for 标签的 JspFragment 。
获取 JspFragment
当在页面上使用一个自定义标签( x:hello )后,会找到相应的 控制器类的实例 ( HelloTag 类的实例 )。
每当页面上出现一个自定义标记,一定会产生一个与它对应的 Java 对象 ( 一个 <x:hello /> 对应一个 HelloTag 实例 )。
通过JVM中的 表示特定标签的那个 对象 可以获得 该标签的标签体对应的 JspFragment 。
在 继承过 SimpleTagSupport 类的类中,都可以通过以下形式获取 JspFragment 对象
JspFragment jspFragment = this.getJspBody();
处理 JspFragment
第一种处理方式:
// 获得 JSP 上下文对象( JspContext )
JspContext jspContext = this.getJspContext();
// 获得输出流 ( 就是JSP页面上的那个 名称是 out 的内置对象 )
JspWriter out = jspContext.getOut() ;
/*** 获得当前标签的标签体对应的 "JSP 碎片" ***/
JspFragment jspFragment = this.getJspBody();
jspFragment.invoke( out ) ;
第二种处理方式:
/*** 获得当前标签的标签体对应的 "JSP 碎片" ***/
JspFragment jspFragment = this.getJspBody();
jspFragment.invoke( null ) ;