JSP自定义标签
jsp自定义标签概念
jsp自定义标签是我们自己定义的一类标签,与C标签相比,
jsp自定义标签可以使用一个标签解决一个类似的问题,
例如下拉框中值的回填,复选框值的回填!
为什么要学习自定义标签
目的是为了让代码的可读性更强,代码不再繁琐重复!
自定义标签的语言特点
<开始标签 属性=“属性值”>标签体</结束标签>
空标签
**没有标签主体内容**
例如:
换行标签和水平线标签
br 和 hr 都是符合空标签的特点
没有标签主体内容
就像 <开始标签/> 这样
按标签类型分,可分为:
Ui标签 select 专门用来展示内容的
控制标签 if/foreach 做流程控制用的
数据标签 set 将某一数据赋值给某变量
实例演示以及自定义生命周期的流程讲解
一、C标签的探讨及实现步骤
1、首先在eclipse中新建一个Dynamic Web Project ,然后新建项目的时候记得勾选上web.xml,也就是这个:
2、导入c标签需要的jar,也就是这两个:
你也可以去点击java resource 下的子目录 找到 Libraries去看jar是否导入进去,如果导入进去了,会出现两个这样的牛奶瓶:
3、在webcontent下新建一个Jsp File ,我这里以Demo1.jsp页面为例:
注意:如果你想使用C标签的话,不仅仅最开始需要导入jar,而且需要在jsp页面头部上导入taglib指令方可使用
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--set out if -->
<c:set var="name" value="lyf"></c:set>
<hr>
<c:out value="${name}"></c:out>
<hr>
<c:if test="true">男</c:if>
<hr>
<c:if test="false">女</c:if>
</body>
</html>
运行结果:
解析:没错,运行结果就是这样的,因为set标签只是单纯地赋值,所以不会输出内容,而out标签是可以展示页面数据的,所以可将set标签的赋值展示出来,而if标签属于控制标签,可做判断,默认为true,所以会输出男 !
二、自定义标签的实现步骤以及注意要点
自定义标签的开发步骤:
1、首先定义一个标签助手类,并且继承BodyTagSupport类!
2、配置好相关的z.tld(配置文件)
3、根据标签的特点去了解自定义生命周期图以及完成该标签助手类
4、在jsp页面调用标签!
5、查看结果是否正确!
注意:
要先继承BodyTagSupport类 记得定义好var和value这两个属性,并添加好相关的set/get方法!
package com.wangqiuping.Tag;
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;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
//skip_body dostartTag()
@Override
public int doStartTag() throws JspException {
pageContext.setAttribute(var, value);
return SKIP_BODY;
}
}
解析:
因为set标签 页面无输出 不需要输出标签体 所以只需调用doStartTag()就好!
返回SKIP_BODY,直接运行到结束标签!
SKIP_BODY 是跳过标签主体的意思!
Out标签:
注意:
要先继承BodyTagSupport类 记得定义好value属性,并添加好相关的set/get方法!
package com.wangqiuping.Tag;
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 = 1973735718608119012L;
private Object value;
private JspWriter out;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
//dostartTag
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
JspWriter out = pageContext.getOut();
try {
out.print(value);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//这里记得抛异常
return SKIP_BODY;
}
}
解析:因为out标签 无标签体 也能输出内容 所以也是直接调用dostartTag()方法,并使用out.print()打印出页面内容就好!
If标签:
注意:
记得继承BodyTagSupport类,并且定义好test属性!
package com.wangqiuping.Tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class IfTag extends BodyTagSupport{
private static final long serialVersionUID = -6184183996611931163L;
private boolean test;
public boolean isTest() {
return test;
}
public void setTest(boolean test) {
this.test = test;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
return test ? EVAL_BODY_INCLUDE :SKIP_BODY;
}
}
解析:因为if标签属于控制标签 用来做判断的 所以只需要调用doStartTag()方法,并且控制好该方法的返回值就好!
相关的配置文件:
我这里以我自己名字命名的,wangqiuping.tld文件为例:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>JSTL 1.1 core library</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>c</short-name>
<uri>/wangqiuping</uri>
<tag>
<name>demo</name>
<tag-class>com.wangqiuping.day01.DemoTag</tag-class>
<body-content>JSP</body-content>
</tag>
<!-- Set标签 -->
<tag>
<name>set</name>
<tag-class>com.wangqiuping.Tag.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>
<!-- Out标签 -->
<tag>
<name>out</name>
<tag-class>com.wangqiuping.Tag.OutTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- If标签 -->
<tag>
<name>if</name>
<tag-class>com.wangqiuping.Tag.IfTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
关于配置的tld文件:
1、tld文件中的short-name其实就是你jsp页面头部中的prefix内容 !
2、 tld中的tag-class最好直接选中你的标签助手类直接Copy Quailied Name,以免出错!
3、Attribute标签中包含的标签内容要符合你自己定义标签的特点!
4、关于Tag标签中标签的设置:
name | 标签名 |
---|---|
tag-class | 标签助手类的全名 |
body-content | 标签主体的内容(一般填jJSP ) |
5、关于Attribute中标签的设置:
name | 属性名 |
---|---|
required | 是否必填 |
rtexprvalue | 是否支持表达式 (true为支持,false为不支持!) |
description | 属性描述 (可写可不写!) |
jsp文件,我这里以我写的index.jsp为例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="w" uri="/wangqiuping" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<hr>
<w:set var="name" value="李易峰"></w:set>
<w:out value="${name}"></w:out>
<hr>
<w:if test="true">李易峰!</w:if>
<w:if test="false">哈哈哈!</w:if>
</body>
</html>
自定义生命周期图:
关于自定义标签生命周期图:
以这张流程图为例,矩形的表示步骤,菱形的表示条件,箭头表示方向!
当Tomcat运行到自定义标签的时候,会先实例化一个标签助手类,在运行开始标签的时候会先调用doStartTag的方法,doStartTag方法有两种返回类型,一种是SKIP_BODY,跳过标签,然后会运行到我们的结束标签,在运行到结束标签的时候,会调用doEndTag方法,而这个doEndTag方法呢,也会有两种类型,一种是SKIP_PAGE,跳过当前页面的剩余内容,也就意味着这个标签之后的页面上的内容都不会显示出来,而另外一种EVAL-PAGE,计算页面的后续内容,也就是在执行完doEndTag标签后,会显示出当前页面的内容;当我们再返回到开始标签的时候,SKIP_BODY-INCLUDE计算并输出主体会去调用doAfterBody这个方法,当跳转到我们的标签主体的时候i,又有两种类型,一种是SKIP_BODY,直接跳过我们的doEndTag结束标签,而另一种呢,就是EVAL-BODY-AGAIN,它会再计算一次我们的主体!
三、注意要点
1、自定义标签引用的时候是在头部引用,并且taglib指令中的prefix最好是和你的tld配置文件中的short-name的值保持一致!以及配置文件中的uri也要和头部中taglib的uri一致!
2、JSP使用的标签对应的助手类 是用来处理业务逻辑的,要记得继承BodyTagSupport类,否则该类中的方法无法调用!
3、助手类中的属性是根据你自己定义的标签带的属性来定义的,例如if标签中有test属性,则if对应的标签助手类中就应含有test属性,并且要添加好对应的set/get方法!
4、标签助手类一般以tag结尾!
最终运行结果
解析:
上面的李易峰是我的自定义set标签赋的值,而下面输出的李易峰!是我自定义的if标签默认的值,这两个值能够同时输出,说明我的自定义标签最终的运行结果是正确的!
总结
jsp自定义标签在一定的程度上解决了代码可读性差,重复代码过多,代码冗余的问题,也为我们在生活中遇到下拉框中回填至时不必使用太多复杂的步骤去解决,同时自己去定义标签,也能让我们更加深入的了解标签的生命周期是如何流转的,今天的分享就到这了,有什么更好的建议或者不足之处欢迎评论留言交流噢!