目录
1、jsp自定义标签库的目的
我们写代码的时候,很多类似重复的很繁琐的代码,为了节省写代码的时间,减少代码冗余,我们可以使用自定义jsp标签来制作符合我们要求的标签,使代码更简洁,可读性更强。
2、jsp自定义标签库的用法
2.1需要的环境
jar包:
标签库的运行离不开tld文件,与web.xml文件在同一目录下:
要使用的标签必须在页面头部导入:
prefix的值是对应的tld文件中的short-name的值,uri的值是对应的tld文件的uri的值:
2.2 标签的语言特点
一般的标签:
<开始标签 属性="属性值">标签体</结束标签>
空标签:
1.<开始标签/> 例如:<br/><hr/> 在这类标签中‘/’代表结束
2.没有标签体的空标签:<开始标签></结束标签>
标签分为三种:数据标签、ui标签、控制标签,以下让我们用c标签来说明这三种标签。
2.3 探究c标签
2.3.1 c标签的简单实例
set标签 设置值 页面无输出 属于数据标签 操作数据的标签:
<c:set var="name" value="zs" ></c:set>
由于set标签无输出,我们配合out标签看效果,out标签 属于ui标签 在界面上看得到,展示内容的标签 输出指定值:
<c:out value="${name }"></c:out>
效果图,set标签和out标签都用水平线分开来看,可见set标签无输出但是给name赋值了,out标签输出了set标签赋的值:
if标签,做判断,test返回值为Boolean类型,true则执行标签体内的内容,false则跳过标签体,属于控制标签,用来做流程控制的标签:
<c:if test="true">男</c:if>
<c:if test="false">女</c:if>
效果图:
2.3.2 自定义标签的开发及使用步骤
1.创建一个标签助手类 继承了BodyTagSupport类;
2.创建标签库描述文件(tld文件),添加自定义标签的配置;
3.tld文件中设置的标签属性必须和助手类中的属性相对应 且助手类要提供对应的get/set方法;
4.在jsp页面头部通过taglib标签导入tld文件;
2.3.4 jsp自定义标签生命周期
这张流程图中矩形的表示执行步骤,菱形的表示条件,箭头表示流向;
这张流程图有以下几种执行情况:
1.doStartTag—>SKIP_BODY—>doEndTag;
2.doStartTag—>EVAL_BODY_INCLUDE—>doAfterBody—>SKIP_BODY—>doEndTag;
3.doStartTag—>EVAL_BODY_INCLUDE—>doAfterBody—>EVAL_BODY_AGAIN—>SKIP_BODY—>doEndTag
大白话解释:
首先是实例化标签助手类,然后调用了doStartTag方法,这个方法有两个返回值,一个是SKIP_BODY,跳过主体,直接到doEndTag方法,他也有两个返回值一个是SKIP_PAGE,跳过当前页面的剩余内容,意思是这个页面上这个标签后的内容都不再执行,doEndTag方法另一个返回值EVAL-PAGE,计算页面的后续内容是指页面上这个标签后面的内容也会执行,最后取消引用助手类;回过头来看doStartTag方法另一个返回值EVAL_BODY_INCLUDE,计算标签主体内容并输出意为标签体内容会执行,然后会到doAfterBody方法,这个方法有两个返回值,一个是SKIP_BODY,跳过主体,直接到doEndTag方法,还有一个EVAL_BODY_AGAIN再计算主体一次,意为再执行标签体一次,最后直到SKIP_BODY到doEndTag方法取消引用助手类。
2.3.5 tld文件中配置文件解释
名词 | 解释 |
---|---|
name | 标签名前缀 如<c:if>中的if;attribute中的name为属性名,例如<c:if test="">中的test |
tag-class | 处理业务的助手类的完整类名 |
body-content | 主体内容 |
attribute | 属性 |
rtexprvalue | 是否支持特殊表达式 |
required | 是否必填 |
3.1 仿写set标签实例
创建一个标签助手类,由于set标签无输出不需要标签体,所以在doStartTag返回值中设置了SKIP_BODY:
package com.zengjing.jsp.day02;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class SetTag extends BodyTagSupport{
private static final long serialVersionUID = 1L;
private String var;
private Object value;
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
@Override
public int doStartTag() throws JspException {
pageContext.setAttribute(var, value);
return SKIP_BODY;
}
}
tld文件中配置,var(变量名)必填,不能为表达式,value(值)必填可为表达式:
<tag>
<name>set</name>
<tag-class>com.zengjing.jsp.day02.SetTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
因为set标签为设置值,与后面的out标签一起展示效果;
3.2 仿写out标签实例
创建一个标签助手类,out标签打印出指定的值:
package com.zengjing.jsp.day02;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class OutTag extends BodyTagSupport{
private static final long serialVersionUID = 1L;
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.print(value);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return SKIP_BODY;
}
}
tld文件中配置,value属性必填可为表达式:
<tag>
<name>out</name>
<tag-class>com.zengjing.jsp.day02.OutTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
效果图,成功赋值并输出:
3.3 仿写if标签实例
创建一个标签助手类,test为true则执行标签体,为false则跳过标签体:
package com.zengjing.jsp.day02;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class IfTag extends BodyTagSupport{
private boolean test;
public boolean isTest() {
return test;
}
public void setTest(boolean test) {
this.test = test;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return test?EVAL_BODY_INCLUDE:SKIP_BODY;
}
}
tld配置,test必填可为表达式:
<tag>
<name>if</name>
<tag-class>com.zengjing.jsp.day02.IfTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
今日总结
总的来说,jsp自定义标签是为了减少代码,增强代码可读性的,理解整个思路就也不是很难了哦,有问题欢迎留言指教熬!拜拜!