首先我们先引用c标签库
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
想必这行代码大家并不陌生,把光标放http://java.sun.com/jsp/jstl/core中,按住Ctrl键我们可以进入到c.tld类,可以看底层代码,在c.tld中我们可以看到:(这里是部分内容)
这是我们jsp界面,在jsp界面中如果要使用c标签,就必须在前面加上这一行代码
更加细心的朋友应该会看到此时引用标签库的那行代码中的prefix="c"
对应着
通过上述两张图中的内容,我们研究c标签的
taglib uri指向了c.tid的
标签内容,从而将c标签引用到当前jsp页面使用
在我们使用标签的时候,本质上是有一个助手类
(tag-class)帮忙处理业务逻辑的
就是org.apache.taglibs.standard.tag.rt.core.SetTag
怎么去查看底层代码呢?例如(c:set标签):
按住Ctrl键,光标移入到c:set上就可以查看到如下图中所示
<c:set var="name" value="zs"></c:set>
通过查询的需求引发了一系列的问题
1、每个查询展示页,都要做分页---->重复性的类似的js代码会很多
2、修改页面,如果遇到了下拉框、复选框回填的情况,如果用c标签的话,if else判断会很多
综上1.2点所诉:当我们遇到查询分页、下拉列表回填、复选框回填…,重复代码过多,代码冗余,不便于阅读修改
如果我们自己能够发明标签会便捷很多,例如:
张三能够看到ab按钮,李四能够看到abcd按钮,王五能够看到abcdef按钮,自己发明标签来实现:
综上所诉最终总结:
学jsp标签的目的,就是为了用一个标签(自定义) 解决类似的一个问题,比如:分页解决分页的问题,下 拉框回填解决下拉框问题
1.双标签:<开始标签>。标签体。(此处。也代表doAfterBody)结束标签>:内容`
2.空标签:
3.带属性的标签:<开始标签 属性名=”属性值”>.标签体.<结束标签>
1.ui标签 :专门用来展示内容(例如:select)
2.控制标签:做流程控制用的(例如:if/foreach)
3.数据标签:c:set将某一数据赋值给某变量
例如:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>自定义标签的第一次内容</title>
</head>
<body>
<!--set(数据标签) out(ui标签) if(控制标签) -->
<!--
现象
set:设置值,页面无输出
out:输出指定值
if:做判断用的
-->
<c:set var="name" value="zs"></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>
在jsp中使用自定义标签,必须先导入标签库,导入示例:<%taglib prefix=”z” uri=”c”%>
注:
1、taglib:标签导入指令
2、 prefix:标签前缀,指定在页面中使用标签时的前缀,容器可以此来判断是自定义标签
3、uri:指定标签库描述文件的uri,注意在此处指定的uri要与标签库.tld描述文件中的uri保持一致,否则在访问jsp页面时会报JasperException
异常
首先我们先来分析一下c:set标签中的助手类的组成部分
(举例,看懂这一个就知道其他的标签的助手类的组成部分啦,基本上每一行都写了注释,重复的就不啰嗦了哈):
助手类组成部分:
jsp页面使用的标签 此时代表(可变)c:set
<name>set</name>
使用标签的时候,本质上是有一个助手类(tag-class)帮忙处理业务逻辑的
<tag-class>org.apache.taglibs.standard.tag.rt.core.SetTag</tag-class>
自定义jsp标签
<body-content>JSP</body-content>
自定义标签的属性定义
<attribute>
属性名
<name>var</name>
是否必填
<required>false</required>
是否支持表达式(el表达式,ognl表达式)
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
看图讲解:
1.矩形代表步骤
2.菱形代表是返回值
3.箭头表示流转方向(箭头代表方向)
流程图中的方法及说明:(如下图)
流程图中的返回值常量及说明:(如下图)
注:.每实例化一个标签助手类需要继承BodyTagSupport
第一步:创建一个标签助手类(继承BodyTagSupport)
第二步:创建标签库描述文件(tld),添加自定义标签的配置
注: tag lib description。该文件必须保存到WEB-INF目录或其子目录,以便于容器启动时加载到内存。
(案例):
现有一个xiaoqing.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>z</short-name>
<uri>/xiaoqing</uri>
<tag>
<name>demo</name>
<tag-class>com.xiaoqing.day01.Demo1</tag-class>
<body-content>JSP</body-content>
<!-- <attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute> -->
</tag>
</taglib>
我们按照上述第6点所画的三条线路走:
第一条线路:
首先创建标签助手类:(内容如下)
package com.xiaoqing.day01;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class Demo1 extends BodyTagSupport{
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doStartTag-----------------------");
return SKIP_BODY;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("doAfterBody-----------------------");
return super.doAfterBody();
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doEndTag-----------------------");
return super.doEndTag();
}
}
然后在jsp界面调用z标签(根据xiaoqing.tld标签文件):(内容如下)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/xiaoqing" prefix="z"%>
<!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>
<z:demo>demo标签内容</z:demo>
</body>
</html>
结果控制台输出为:调用了doStartTag和doEndTag方法
第二条线路:
首先创建标签助手类:(内容如下)
package com.xiaoqing.day01;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class Demo1 extends BodyTagSupport{
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doStartTag-----------------------");
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("doAfterBody-----------------------");
return EVAL_PAGE;
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doEndTag-----------------------");
return super.doEndTag();
}
}
然后在jsp界面调用z标签(根据xiaoqing.tld标签文件):(内容如下)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/xiaoqing" prefix="z"%>
<!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>
<z:demo>demo标签内容</z:demo>
</body>
</html>
第三条线路:
首先创建标签助手类:(内容如下)
package com.xiaoqing.day01;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class Demo1 extends BodyTagSupport{
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doStartTag-----------------------");
return EVAL_BODY_INCLUDE;
}
@Override
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
System.out.println("doAfterBody-----------------------");
return EVAL_BODY_AGAIN;
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
System.out.println("doEndTag-----------------------");
return super.doEndTag();
}
}
然后在jsp界面调用z标签(根据xiaoqing.tld标签文件):(内容如下)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/xiaoqing" prefix="z"%>
<!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>
<z:demo>demo标签内容</z:demo>
</body>
</html>
第一步:建立.tld文件(位置放入web-info下)
在xiaoqing.tld中定义(set out if )标签,文件配置内容如下
<?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>z</short-name>
<uri>/xiaoqing</uri>
<tag>
<name>demo</name>
<tag-class>com.xiaoqing.day01.Demo1</tag-class>
<body-content>JSP</body-content>
</tag>
<!--标签 -->
<tag>
<!--标签名 -->
<name>set</name>
<!--助手类的全名 -->
<tag-class>com.xiaoqing.day02.SetTag</tag-class>
<!--主体内容 一般写JSP -->
<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>
<tag>
<name>out</name>
<tag-class>com.xiaoqing.day02.OutTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!--属性名 -->
<name>value</name>
<!--是否必填 -->
<required>true</required>
<!--是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>if</name>
<tag-class>com.xiaoqing.day02.IfTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<!--属性名 -->
<name>test</name>
<!--是否必填 -->
<required>true</required>
<!--是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
第二步:分别建立set out if 的标签助手类
set标签助手类(内容如下,里面注释也打了):
package com.xiaoqing.day02;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class SetTag extends BodyTagSupport{
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 {
// TODO Auto-generated method stub
//赋值:把value值赋值给var
pageContext.setAttribute(var, value);
return SKIP_BODY;//由于set标签没有标签主体,所以跳过标签主体,只需要设置值
}
}
out标签助手类(内容如下,里面打了注释):
package com.xiaoqing.day02;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* 属于UI标签:标签本身自己能输出内容,不需要借助标签体输出,所以跳过标签体
* @author 晴sister
*
* https://i.csdn.net/#/uc/profile
*/
public class OutTag extends BodyTagSupport{
private static final long serialVersionUID = 4269386557221194950L;
private Object value;//需要打印的值
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
JspWriter out = pageContext.getOut();//获取out
try {
out.print(value);//打印value值
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return SKIP_BODY;//跳过标签主体
}
}
if标签助手类(内容如下,里面打了注释):
package com.xiaoqing.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
//这里运用了三元运算符:如果test为true,那么就执行EVAL_BODY_INCLUDE:计算主体并输出
//如果test为false,那么就执行SKIP_BODY:跳过标签主体
return test?EVAL_BODY_INCLUDE:SKIP_BODY;
}
}
最后我们在jsp界面中来验证一下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="/xiaoqing" prefix="z"%>
<!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>自定义标签的第一次内容</title>
</head>
<body>
<!--set(数据标签) out(ui标签) if(控制标签) -->
<!--
现象
set:设置值,页面无输出
out:输出指定值
if:做判断用的
研究c标签
taglib uri指向了c.tld的uri标签内容,从而将c标签引用到当前jsp页面使用
使用标签的时候,本质上是有一个助手类(tag-class)帮忙处理业务逻辑的
org.apache.taglibs.standard.tag.rt.core.SetTag
助手类组成部分:
jsp页面使用的标签 此时代表(可变)c:set
<name>set</name>
使用标签的时候,本质上是有一个助手类(tag-class)帮忙处理业务逻辑的
<tag-class>org.apache.taglibs.standard.tag.rt.core.SetTag</tag-class>
自定义jsp标签
<body-content>JSP</body-content>
自定义标签的属性定义
<attribute>
属性名
<name>var</name>
是否必填
<required>false</required>
是否支持表达式(el表达式,ognl表达式)
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
-->
<c:set var="name" value="zs"></c:set>
<hr>
<c:out value="${name }"></c:out>
<hr>
<c:if test="true">男</c:if>
<hr>
<c:if test="false">女</c:if>
<hr>
<!--仿写c标签的 set out if 标签 -->
<h2>仿写c标签的 set out if 标签 </h2>
<z:set var="sex" value="gay"></z:set>
<z:out value="${sex }"></z:out>
<hr>
<z:if test="true">gay</z:if>
<hr>
<z:if test="false">baihe</z:if>
</body>
</html>
运行结果为:
从结果中可以看出,我们是仿写c标签是成功的,哦耶!!!!!
今天就到这里了,后面会继续更新自定义标签,goodbye!!!!