自定义标签的详细使用讲解【上】(一)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 自定义标签的详细使用讲解【上】

一、前言

1.什么是自定义标签

在了解什么是自定义标签之前,我们先了解什么是标签。

标签(Tag):是一种特殊的语言构造,通常用于在一些具有特定功能的语言中指定标记或元数据,从而实现一些特殊的效果或功能。很多与“ML”结尾的语言都是标记语言,比如:HTML,XML,XHTML,VML等等。标记语言与其他语言一样,也需要运行它们的环境,比如HTML的运行环境时浏览器,XML也要自己的解析和运行的环境。

自定义标签(Custom Tag):是指在JSP中,开发者自行定义的可扩展标记(Tag),用于扩展和增强JSP的功能。可以使用自定义标签可以实现一些自定义逻辑,如访问Web服务、执行数据库操作、生成HTML代码、进行数据处理等复杂操作;还可以实现基于标签的流程控制、数据模型、动态样式等功能。

2.自定义标签的两种类型

简单标签

指不包含主体内容的标签,简单标签的处理一般是基于标签的属性和参数,例如<br>、<hr>

标签体标签

是指包含主体内容的标签,标签体标签的处理需要对标签的主体内容进行解析和处理,例如<if>标签和<foreach>标签等。

3.为什么要使用自定义标签

1.易于维护和重用

自定义标签将复杂的逻辑封装在单一的标签中。这使得代码更易于维护和重用,可以将一些常用的逻辑封装在标签中,避免代码重复和冗余。

2.提高代码的可读性

通过使用自定义标签,可以将业务逻辑和代码标签化,从而提高代码的可读性和可维护性。标签化的代码更符合人类的思维模式,理解和调试也更为方便。

3.分离业务和呈现逻辑

使用自定义标签可以分离业务逻辑和呈现逻辑,帮助开发者更好地实现MVC(Model-View-Controller)设计模式,提高应用程序的可扩展性和重用性。

4.提高应用程序的性能

使用自定义标签可以将需要多次重复执行的代码封装在标签中,从而减少代码重复和冗余,提高应用程序的性能。

4.使用场景

我们在做Web项目的时候,肯定是多人开发,但是有很多的代码是相同的,为了减少代码冗余,我们就可以自定义标签,共大家使用,提高效率也方便维护。

二、自定义标签的使用

1自定义标签的生命周期

由图可知我们大致分为四个阶段

实例化阶段、初始化阶段、使用阶段和实例释放阶段

2.创建自定义标签

看图很难理解,所以我们接下来直接上代码。

模拟c标签中的out标签

2.1.编写助手类

package c;
import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
 * 自定义标签继承BodyTagSupport 作用:用于在jsp页面输出内容
 * 
 * @author Java方文山
 *
 */
public class OutTag extends BodyTagSupport {
  private String val;// out标签需要输出的属性值
  private String defaultVal;// out标签默认输出属性值
  public void setVal(String val) {
    this.val = val;
  }
  public void setDefaultVal(String defaultVal) {
    this.defaultVal = defaultVal;
  }
  // 重写doStartTag方法
  @Override
  public int doStartTag() {
    // 因为要在页面输出内容,所以先获取out对象
    JspWriter out = this.pageContext.getOut();
    try {
      // 判断标签属性有无值
      if (this.val == null || "".equals(this.val)) {
        // 标签属性为空输出默认值
        out.print(this.defaultVal);
      } else {
        // 标签属性不为空输出标签属性值
        out.print(this.val);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    // 跳过主体
    return SKIP_BODY;
    /*
     * SKIP_BODY以后最后用这种写法来写(成员变量), 不然别的程序员看不懂你写的代码,利用成员变量更加理解以及维护代码。
     * 
     */
  }
}

2.2.编写标签库的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路径-->
  <uri>/xw</uri>
  <tag>
    <!-- 标签名 -->
    <name>out</name>
    <!-- 标签助手类 -->
    <tag-class>c.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>
</taglib>

2.3.jsp页面引用标签

<%@page import="c.TestForeach"%>
<%@page import="c.Student"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 引入自定义标签-->
    <%@taglib prefix="xw" uri="/xw" %>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>自定义标签</title>
</head>
<body>
<!--自定义out标签输出 -->
<xw:out val="你好我是自定义标签out,val属性输出"/>
<br>
<!--自定义out标签EL表达式使用  -->
<%
request.setAttribute("name", "我是在作用域的文件,利用EL表达式获取");
%>
<xw:out val="${name }"/>
<br>
<!--自定义out标签defaultVal属性输出 -->
<%
request.setAttribute("x", null);
%>
<xw:out val="${x}" defaultVal="我是out标签的默认值输出1"/>
<xw:out val="" defaultVal="我是out标签的默认值输出2"/>
<br>
<hr>
</body>
</html>
</body>
</html>

浏览器输出结果

2.4.总结

由上可知,我们自定义标签只需要三步,①编写助手类②编写tld文件③页面引入自定义。

①编写助手类:编写一个普通的Java类继承BodyTagSupport类,为什么这里是继承类而不是是实现接口,因为BodyTagSupport类里的功能,开发人员可能不需要,实现接口就必须重写方法,可能会出错,而继承则是开发人员重写自己所需要的方法即可。在助手类里面定义自定义标签所需的属性,并编写set方法(后期需要通过反射往实例里面插入值)。重写doStartTag方法,并加上@Override注解。

②编写tld文件:tld文件可变内容就是<tag>里的元素,其他内容“cv”操作即可,自定义标签的属性名字必须和助手类一致,而且自定义标签的助手类路径名必须是正确的全路径名

③页面引入自定义:直接在需要自定义标签的地方<%@taglib prefix="xw" uri="/xw" %>引用即可,uri就是自己在tld文件所写的。

三、解析自定义标签

助手类里的return值

返回值 含义
SKIP_BODY 跳过主体
EVAL_BODY_INCLUDE 计算标签主体内容并输出
EVAL_BODY_AGAIN 再次计算主体一次
EVAL_PAGE 计算页面的后续部分
SKIP_PAGE 跳过页面的后续部分

1.为什么要重写doStartTag方法?

在自定义标签处理器中,doStartTag()方法是必须要实现的,因为它是JSP引擎在解析页面时调用的第一个方法,并且用于处理标签的开始标记。

如果不重写doStartTag()方法,那么JSP引擎会默认返回 SKIP_BODY 的值,也就是说,页面在遇到自定义标签时,标签体内的所有内容都将被略过不被执行。

2.自定义标签的工作流程

编译器看不懂“jsp文件”,它会先转成java文件,然后先通过jsp页面的引用自定义标签路径,找到tld文件,然后通过找到使用<tag>编写的标签找到指定的<tag-class>,通过里面的全路径名反射实例(助手类)调用doStartTag方法对标签进行处理。

相关文章
|
10月前
|
XML Java 数据格式
自定义jsp标签1
自定义jsp标签1
27 0
|
8月前
|
XML Java 程序员
自定义JSP标签
自定义JSP标签
|
8月前
|
Java
自定义标签(下)
自定义标签(下)
|
9月前
|
XML Java 数据格式
自定义标签
自定义标签
|
9月前
|
Java 程序员 开发者
自定义标签-下
自定义标签-下
25 0
|
9月前
|
XML Java API
自定义JSP标签【上】
自定义JSP标签【上】
30 0
|
9月前
|
安全 Java
自定义JSP标签01
自定义JSP标签01
24 0
|
10月前
|
Java 数据库
自定义标签的详细使用讲解【下】
自定义标签的详细使用讲解【下】
23 0
|
10月前
自定义标签的详细使用讲解【上】(二)
自定义标签的详细使用讲解【上】(二)
24 0
|
10月前
|
XML Java 数据格式
自定义jsp标签2
自定义jsp标签2
32 0