当前位置:网站首页>JSP自定义标签(一篇学会,每一行代码都有注释)
JSP自定义标签(一篇学会,每一行代码都有注释)
2022-07-20 01:47:00 【Champion_me】
这里写目录标题
学习JSP标签之前我们先简单了解一下什么是标签。
一、什么是标签?
标记语言,是一种注释文本的语言,以便于计算机可以操作。很多与“ML”结尾的语言都是标记语言,比如:HTML,XML,XHTML,VML等等。
标记语言与其他语言一样,也需要运行它们的环境,比如HTML的运行环境时浏览器,XML也要自己的解析和运行的环境。
基本结构:
<开始标签>标签体</结束标签>
空标签:
<开始标签 属性名=“属性值”/></结束标签>
<开始标签 属性名=“属性值”/>
二、JSP标签库是什么?
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
根据JSTL标签所提供的功能,可以将其分为5个类别。
- 核心标签
- 格式化标签
- SQL 标签
- XML 标签
- JSTL 函数
三、为什么要学习JSP自定义标签?
使用JSP更加的方便,例如我们在写分页时,是需要自己手动写的,但是学了JSP自定义标签后,我们就可以把分页功能封装成标签,日后就不需要很麻烦的写分页了,只需要调用分页标签即可。
四、处理流程 (JSP自定义标签生命周期图)
下面有关于这个周期图的流程分析
例如:我们以前用的JSP里面的C标签,那他是怎么搞得嘞?首先页面先去执行,当执行碰到我们的C标签,他会首先看我们的助手类(这个助手类怎么去写我们先不管,助手类是帮我们处理这个标签,封装功能),然后在看我们这个助手类有没有被实例化,如果被实例化之后就会调用doStartTag这个方法(助手类肯定会有这个方法,这是一个规范),调用这个方法之后看这个方法的返回值,如果返回值等于 EVAL_BODY_INCLUDE(这是一个常量)表示它有标签体,我需要继续去处理我的标签体;那如果返回值等于 SKIP_BODY 就说明它没有标签体要处理或者是有标签体也不需要处理(比如说if标签),然后我们继续按着周期图走,然后到doEndTag标签(就是结束标签),它会有两个值,EVAL_PAGE(意思是我去继续处理标签下面的页面元素),SKIP_PAGE(意思就是跳过页面)。
如果说这里面需要去处理的话呢(有标签体需要去处理),那么就会调用doAfterBody,然后会去判断这个方法的返回值,看是不是要继续去进行处理,如果说要继续去处理,那么就会EVAL_BODY_AGAIN
循环回来继续调用doAfterBody,如果不需要那么就继续SKIP_BODY。为什么有这一步?我们想一下C标签,C标签我们是不是给他一个结果集,他要给我们循环结果集,循环给我们显示每一行数据,那是不是我们集合还有值我们是不是要回去继续处理,如果集合里面没有值我们就跳过去了,实际上这一步就是帮助我们去处理循环标签的。
上面的这些可能有点懵逼,没事我们接下来做几个自定义标签实例,慢慢理解
五、如何自定义标签
常见自定义标签主要步骤:
- 编写助手类
- 编写标签库描述文件(tld)
- 在页面上引入标签使用
六、标签类型
- UI标签, 输出页面元素
- 控制标签, 如if标签,foreach标签等
- 数据标签,用于向页面输入数据
然后下来我们就用代码来自定义几个标签(每一行代码都有详细的注释哦)
七、自定义out标签
第一步建立助手类
OutTag.java
package com.zking.mymvc.tag;
import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.mysql.jdbc.StringUtils;
/** * 助手类,标签处理类 * * @author zjjt * */
public class OutTag extends BodyTagSupport {
// 我要给他做成一个合法的标签处理类,那么就必须extends BodyTagSupport
private String val;// 因为我们要自定义的是out标签,而out标签是要向页面输出值的,那么定义的这个val就是向页面输出的值(值从哪里来我们先别管)
private String defaultVal;// 这个就是默认值,如果val为null,那么就显示这个默认值
// 因为这两个值我们需要以某种方式注入(set)进来,所以就需要下面的get和set方法
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String getDefaultVal() {
return defaultVal;
}
public void setDefaultVal(String defaultVal) {
this.defaultVal = defaultVal;
}
// 下面这个方法是在父类里面有的
@Override
public int doStartTag() {
// out是数据标签,要把值写到页面上去
JspWriter out = this.pageContext.getOut();// 有了这个输出流
try {
// 然后我们就可以进行判断了
// 判断val是否为空,下面这个如果我们不用MySQL就挂了,那就要自己写个帮助类
if (StringUtils.isNullOrEmpty(val)) {
// 然后我们通过输出流,写到页面
out.println(this.defaultVal);
}else {
out.println(this.val);
}
} catch (IOException e) {
e.printStackTrace();
}
//数据标签里面没有标签体,它就是输出数据的,那么它就是个空标签,所以我们直接SKIP_BODY,直接跳过
return SKIP_BODY;
//我们就不用去管那个doEndTag了,我们的这个BodyTagSupport不是接口,它这里会有doEndTag方法的默认实现的
}
}
第二步建立标签库的描述文件,注意只能放在WEB-INF这下面
mytag.tld
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"><!--帮我们进行验证的 -->
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<tlib-version>1.0</tlib-version><!-- 表示标签库的版本号 -->
<jsp-version>1.2</jsp-version><!-- 示标签库的版本号 -->
<short-name>Simple Tags</short-name>
<uri>/zking</uri><!-- 需要注意的是这个,我们有了标签库文件过后,我们要根据这个引入标签 -->
<!-- 接下来就开始定义我们的标签 -->
<tag>
<!-- 标签名 -->
<name>out</name>
<!-- 标签助手类 -->
<tag-class>com.zking.mymvc.tag.OutTag</tag-class><!-- 有一个标签的实现类,碰到这个标签之后,实例化助手类,通过标签库这个描述文件里会有这个类的权限定名,然后通过反射机制动态实例化 -->
<!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 -->
<body-content>empty</body-content>
<attribute>
<!-- 属性名, OutTag类中的val属性相匹配 -->
<name>val</name>
<!-- 表示该属性为必要的属性(必须要输入的) -->
<required>true</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>true</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签val属性,用于输出val的值</description>
</attribute>
<attribute>
<!-- 属性名, OutTag类中的defaultVal属性相匹配 -->
<name>defaultVal</name>
<!-- 表示该属性为必要的属性 -->
<required>false</required>
<!-- 该属性可以接受EL表示式的值 -->
<rtexprvalue>false</rtexprvalue>
<!-- 标签描述,用于说明标签的作用 -->
<description>out标签,如val属性值为空,则输出该默认值</description>
</attribute>
</tag>
<!-- 一个标签库是可以有多个标签的,所有我们的if标签直接在里面写就可以了 -->
<tag>
<name>if</name>
<tag-class>com.zking.mymvc.tag.IfTag</tag-class>
<body-content>jsp</body-content><!-- 他有一个标签体,条件成立显示标签里的内容,条件不成立不显示 -->
<description>if标签</description>
<attribute>
<name>test</name><!-- 这里的name要跟帮助类的属性一致 -->
<required>true</required><!-- 条件是必须的 -->
<rtexprvalue>true</rtexprvalue><!-- 需要支持EL表达式 -->
</attribute>
</tag>
</taglib>
再就是测试标签是否可用
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 第一步引入标签库 -->
<%@taglib prefix="z" uri="/zking" %><!-- 注意这里的uri要与标签库那个uri一样 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- out标签的测试 -->
<%
request.setAttribute("name","");
%>
<z:out val="${name}" defaultVal="李四"/>
<p>
<!-- if标签的测试 -->
<z:if test="${100 == 100}">
测试if(100 == 100)
</z:if>
<z:if test="${100 == 200}">
测试if(100 == 100)
</z:if>
</body>
</html>
八、自定义 if 标签
第一步也是先写帮助类
IfTag.java
package com.zking.mymvc.tag;
import javax.servlet.jsp.tagext.BodyTagSupport;
/** * 助手类,标签处理类 * @author zjjt * */
public class IfTag extends BodyTagSupport{
private boolean test;//因为我们要写if标签,那么就有条件需要判断(用来验证的)
//条件是从外面注入的,所以要set方法,get方法可写可不写
public boolean isTest() {
return test;
}
public void setTest(boolean test) {
this.test = test;
}
/** * 重写父类的方法 */
@Override
public int doStartTag() {
//然后我们就可以进行判断了
if(this.isTest()) {
//如果这个方法返回的是true,我需要继续处理这个标签,所以要return EVAL_BODY_INCLUDE
return EVAL_BODY_INCLUDE;
}
return SKIP_BODY;//如果if条件不成立,那我们直接跳过
}
}
第二步建立标签库的描述文件,注意只能放在WEB-INF这下面(因为一个标签库是有多个标签的,所以if标签在上面的那个标签库)
第三步测试也在上面的index.jsp
边栏推荐
猜你喜欢
QT_ QSS file easy-to-use tutorial
Understand the MySQL architecture design in one article, and don't worry about the interviewer asking too much
QT_qss文件简易使用教程
Which domestic API tool is better? It turned out to be it
Qt:Could not find qmake spec ‘default’. Error while parsing file xxx. pro. Giving up
Vivo official website app full model UI adaptation scheme
软件测试如何快速入门
How to get started quickly in software testing
acwing 870. 约数个数
2022/7/19
随机推荐
xing号
AVL tree
数据库系统原理与应用教程(026)—— MySQL 修改表中数据(二):删(delete from)
DNS域名解析
Ppde Q2 welcome | welcome 22 AI developers to join the propeller developer technical expert program!
PPDE第二季度迎新 | 欢迎22位AI开发者加入飞桨开发者技术专家计划!
Introduction to audio and video -- Analysis of H.264 coding (macroblock + slice + frame)
一文了解 NebulaGraph 上的 Spark 项目
我的书《Oracle Database In-Memory架构与实践》出版了
ISecOps智能安全运营技术体系框架
Blurred photos, second high-definition big picture, flying propeller ppde takes you to reproduce the image restoration model cmfnet
Frontier and application of data security technology from the perspective of compliance
Unity shader shader learning (2)
Vivo official website app full model UI adaptation scheme
Explain the RDB and AOF of redis in detail
300000 prize pool is waiting for you to fight! Natural language processing (NLP) competition collection is coming
acwing 868. 筛质数
VMware 启动报错:Exception 0xc0000005和windwos11没有Hyper-V的解决方法
acwing 870. 约数个数
Baidu PaddlePaddle easydl helps manufacturing enterprises with intelligent transformation