自定义标签定义:是用户定义的JSP语言元素。扩展名为tld的文件(tag标签的配置文件),通常放在WEB-INF下面。
自定义标签的开发及使用步骤
思路
1.1 创建一个标签助手类(继承BodyTagSupport)
标签属性必须助手类的属性对应、且要提供对应get/set方法 rtexprvalue
1.2 创建标签库描述文件(tld),添加自定义标签的配置
注:tld文件必须保存到WEB-INF目录或其子目录
1.3 在JSP通过taglib指令导入标签库,并通过指定后缀
访问自定义标签
标签生命周期
生命周期图如下(首先先了解别人写的c标签库)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716200214786.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
1.准备自定义标签库助手DemoTag.Java
package com.wxm.jsp.tag; import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.BodyTagSupport;
public class DemoTag extends BodyTagSupport {
/** * 序列号的作用:方便对象序列化 * 序列化:对象按照特定的规则持久的存储到硬盘中 */
private static final long serialVersionUID = -8850550555242137344L;
private String test;
public String getTest() {
return test;
}
public void setTest(String test) { t
his.test = test;
}
@Override
public int doStartTag() throws JspException {
System.out.println(test);
System.out.println("doStartTag----------");
return super.doStartTag();
}
@Override
public int doAfterBody() throws JspException {
System.out.println("doAfterBody----------");
return super.doAfterBody();
}
@Override
public int doEndTag() throws JspException {
System.out.println("doEndTag----------");
return super.doStartTag();
}
}
2.创建标签库描述文件(tld),添加自定义标签的配置
.准备在web-inf下新建file文件(后缀名为tld)我这里是wxm.tld
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716200435171.png)
<?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>wxm 1.1 core library</description>
<display-name>wxm core</display-name>
<tlib-version>1.1</tlib-version><!-- 标签库的版本号 -->
<short-name>c</short-name><!-- 标签库的简称 -->
<uri>/wxm</uri><!--你标签库引用的uri -->
</taglib>
3.Demo1.jsp来调用显示
注意:在JSP通过taglib指令导入标签库,并通过指定后缀
访问自定义标签
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716200647673.png)
<wxm:demo test="xxx"></wxm:demo>
运行到服务器的效果是
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201022161.png)
可以看出生命周期走势为
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201058681.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
当定义了标签体,代码
<wxm:demo test="xxx">标签体内容</wxm:demo>
效果为
可见 ,生命周期走势为
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201200278.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
还是之前的DemoTag.Java把对应的代码改为
@Overridepublic int doAfterBody() throws JspException {
System.out.println("doAfterBody----------");
return EVAL_BODY_AGAIN;
}
@Override
public int doEndTag() throws JspException {
System.out.println("doEndTag----------");
return super.doEndTag();
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201610564.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201810306.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
这演示了生命周期的第三条路 就是循环 最常见的标签就是foreach
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716201831533.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
敲重点来了!!!
SKIP_BODY:跳过主体
EVAL_BODY_INCLUDE:计算标签主体内容并[输出] EVAL_BODY_BUFFERED:计算标签主体内容并[缓存]
EVAL_PAGE:计算页面的后续部分
SKIP_PAGE:跳过页面的后续部分
EVAL_BODY_AGAIN:再计算主体一次
练习:开发出c:out/c:foreach/c:if/
我这里通过别人写好的c标签库和自己写的标签分别对比
![在这里插入图片描述](https://img-blog.csdnimg.cn/2019071620243114.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)
- 上面已经建好的WEB-INF下的wxm.tld2. 新建DemoTagOut.jsp
- 新建DemoTagOut.jsp
package com.wxm.jsp.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/** * 自定义out标签处理类 BodyTagSupport(TagSupport)
* @author 2019071003 * */
public class DemoTagOut extends BodyTagSupport {
/** * 序列号的作用:方便对象序列化 * 序列化:对象按照特定的规则持久的存储到硬盘中 */
private static final long serialVersionUID = 221407492247778768L;
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override public int doStartTag() throws JspException { //输出value值 try {
pageContext.getOut().println(value);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// EVAL_BODY_INCLUDE显示文本内容
// SKIP_BODY不显示标签中(文本)的内容
return EVAL_BODY_INCLUDE;
}
@Override
public int doEndTag() throws JspException {
// EVAL_PAGE继续显示标签下面的内容
// SKIP_PAGE 显示完该标签内容后,不再显示后面的标签内容,直接跳转到</html> return EVAL_PAGE;
}
}
- 新建DemoTagIf.jsp
package com.wxm.jsp.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/** * 自定义if标签处理类 BodyTagSupport(TagSupport) * @author 2019071003 * */
public class DemoTagIf extends BodyTagSupport {
/** * 序列号的作用:方便对象序列化 * 序列化:对象按照特定的规则持久的存储到硬盘中 */
private static final long serialVersionUID = -4319841194548962012L;
private Boolean test;
public Boolean getTest() {
return test;
}
public void setTest(Boolean test) {
this.test = test;
}
@Override public int doStartTag() throws JspException {
//如果为true则显示文本中的内容,否则不显示
if(test) {
return EVAL_BODY_INCLUDE;
}else {
return SKIP_BODY;
}
}
@Override
public int doEndTag() throws JspException {
//继续显示标签下的内容
return EVAL_PAGE;
}
}
- 新建DemoTagForeach.jsp
package com.wxm.jsp.tag;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/** * 自定义foreach标签处理类 BodyTagSupport(TagSupport)
* @author 2019071003 * */
* public class DemoTagForeach extends BodyTagSupport { /** * 序列号的作用:方便对象序列化 * 序列化:对象按照特定的规则持久的存储到硬盘中 */
* private static final long serialVersionUID = 221407492247778768L; /** * items属性 */
private List<Object> items=new ArrayList<>();
/** * var属性 */
private String var; public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doStartTag() throws JspException {
//如果集合没有值则跳过,否则进行输出
if(items==null||items.size()==0) {
return SKIP_BODY;
}else {
//得到集合信息
Iterator<Object> it=items.iterator();
//放入到请求域中
pageContext.setAttribute("it", it);
Object v=it.next();
pageContext.setAttribute(var, v);
//显示文本内容
return EVAL_BODY_INCLUDE;
}
}
@Override
public int doAfterBody() throws JspException {
// 得到请求域中的值
Iterator<Object> it=(Iterator<Object>)
pageContext.getAttribute("it");
if(it.hasNext()) {
Object v=it.next();
pageContext.setAttribute(var, v);
//循环
return EVAL_BODY_AGAIN;
}else {
//否则 跳过,不输出
return SKIP_BODY;
}
} @
Override
public int doEndTag() throws JspException {
//继续读取标签的值
return EVAL_PAGE;
}
}
- 最后用上之前建的显示类Demo1.jsp
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@taglib uri="/wxm" prefix="wxm"%>
<%@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>Insert title here</title>
<%-- <c:set value="zs" var="name">
</c:set><c:out value="${name}">
</c:out><c:if test="true">ls</c:if><
c:if test="false">ww</c:if> --%>
</head>
<!--1.demoTag -->
<%-- <wxm:demo test="xxx">标签体内容</wxm:demo> --%>
<body>
<!-- 自定义out的使用 -->
<ul><wxm:out value="这是自定义out">
</wxm:out><c:out value="c里面的标签out">
</c:out>
</ul>
<!-- 自定义标签if的使用 -->
<ul><wxm:if test="true">--wxm:true--</wxm:if>
<wxm:if test="false">wxm:false</wxm:if>
<c:if test="true">ls</c:if>
<c:if test="false">ww</c:if>
</ul>
<!-- 自定义标签Foreach的使用 -->
<% List<Object> list=new ArrayList<>();
for(int i=1;i<11;i++){
list.add("wxm"+i);
}
request.setAttribute("list", list);
%>
<ul>
<wxm:foreach items="${list}" var="i">
<li>${i}</li>
</wxm:foreach>
</ul>
</body>
</html>
最后效果,到现在已经完成啦
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190716202728552.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDEwNjMzNA==,size_16,color_FFFFFF,t_70)