自定义标签库 ||(或) jsp标签(一)

自定义标签库 ||(或) jsp标签

  • 1、jsp标签学什么(思考)?
      • 1.1、 了解我们所使用的c标签如何制作出来?
      • 1.2、从实际出发,c标签的使用相较而言有哪些不足之处
      • 1.3、 结合1.1点,如何制作出符合自己要求的标签、
  • 2.标签的语言特点
  • 3.标签分类
  • 4、在JSP中引入标签库
  • 5、助手类该怎么写?
  • 6、JSP自定义标签生命周期图
  • 7、自定义标签的开发及使用步骤
  • 8.仿写c标签中的set out if标签(案例)

1、jsp标签学什么(思考)?

1.1、 了解我们所使用的c标签如何制作出来?

首先我们先引用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标签(一)_第1张图片
这是我们jsp界面,在jsp界面中如果要使用c标签,就必须在前面加上这一行代码自定义标签库 ||(或) jsp标签(一)_第2张图片
更加细心的朋友应该会看到此时引用标签库的那行代码中的prefix="c"对应着
c
自定义标签库 ||(或) jsp标签(一)_第3张图片

通过上述两张图中的内容,我们研究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>

自定义标签库 ||(或) jsp标签(一)_第4张图片

1.2、从实际出发,c标签的使用相较而言有哪些不足之处

1.3、 结合1.1点,如何制作出符合自己要求的标签、

通过查询的需求引发了一系列的问题
1、每个查询展示页,都要做分页---->重复性的类似的js代码会很多
2、修改页面,如果遇到了下拉框、复选框回填的情况,如果用c标签的话,if else判断会很多
综上1.2点所诉:当我们遇到查询分页、下拉列表回填、复选框回填…,重复代码过多,代码冗余,不便于阅读修改

如果我们自己能够发明标签会便捷很多,例如:
张三能够看到ab按钮,李四能够看到abcd按钮,王五能够看到abcdef按钮,自己发明标签来实现:

综上所诉最终总结
学jsp标签的目的,就是为了用一个标签(自定义) 解决类似的一个问题,比如:分页解决分页的问题,下 拉框回填解决下拉框问题

2.标签的语言特点

1.双标签:<开始标签>。标签体。(此处。也代表doAfterBody)内容`
2.空标签:

3.带属性的标签:<开始标签 属性名=”属性值”>.标签体.<结束标签>

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标签(一)_第5张图片

4、在JSP中引入标签库

在jsp中使用自定义标签,必须先导入标签库,导入示例:<%taglib prefix=”z” uri=”c”%>
注:
1、taglib:标签导入指令
2、 prefix:标签前缀,指定在页面中使用标签时的前缀,容器可以此来判断是自定义标签
3、uri:指定标签库描述文件的uri,注意在此处指定的uri要与标签库.tld描述文件中的uri保持一致,否则在访问jsp页面时会报JasperException异常

5、助手类该怎么写?

首先我们先来分析一下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>

6、JSP自定义标签生命周期图

自定义标签库 ||(或) jsp标签(一)_第6张图片
(流程图)

				看图讲解:
					1.矩形代表步骤
					2.菱形代表是返回值
					3.箭头表示流转方向(箭头代表方向)

流程图中的方法及说明:(如下图)
自定义标签库 ||(或) jsp标签(一)_第7张图片
流程图中的返回值常量及说明:(如下图)
自定义标签库 ||(或) jsp标签(一)_第8张图片

流程图中有三条线路可行(如下图):
自定义标签库 ||(或) jsp标签(一)_第9张图片

注:.每实例化一个标签助手类需要继承BodyTagSupport

7、自定义标签的开发及使用步骤

第一步:创建一个标签助手类(继承BodyTagSupport)

第二步:创建标签库描述文件(tld),添加自定义标签的配置
注: tag lib description。该文件必须保存到WEB-INF目录或其子目录,以便于容器启动时加载到内存。

自定义标签库 ||(或) jsp标签(一)_第10张图片

(案例):
现有一个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方法
自定义标签库 ||(或) jsp标签(一)_第11张图片

第二条线路:
首先创建标签助手类:(内容如下)

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>

结果控制台输出为
自定义标签库 ||(或) jsp标签(一)_第12张图片

第三条线路:
首先创建标签助手类:(内容如下)

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>

结果控制台输出为:就一直进入死循环
自定义标签库 ||(或) jsp标签(一)_第13张图片

8.仿写c标签中的set out if标签(案例)

第一步:建立.tld文件(位置放入web-info下)

自定义标签库 ||(或) jsp标签(一)_第14张图片
在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>

运行结果为:
自定义标签库 ||(或) jsp标签(一)_第15张图片
从结果中可以看出,我们是仿写c标签是成功的,哦耶!!!!!

今天就到这里了,后面会继续更新自定义标签,goodbye!!!!

你可能感兴趣的:(自定义标签库 ||(或) jsp标签(一))