自定义标签

Posted -草根-颜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义标签相关的知识,希望对你有一定的参考价值。

使用标签可以替换jsp页面上的脚本,让页面更加简洁,维护更加方便,增加程序安全性。

在javaee api中有一个接口javax.servlet.jsp.tagext.JspTag,它是所有的标签的根接口。

在jsp2.0以后,定义了一个更加简单的javax.servlet.jsp.tagext.SimpleTag,这个接口就描述了如何自定义标签。

标签的分类:

  • 传统标签
  • 简单标签SimpleTag

SimpleTag体系

     SimpleTag有一个实现类SimpleTagSupport,自定义标签类一般会继承它。

定义一个标签的步骤:

  1. 定义一个标签类让它实现SimpleTag接口或继承SimpleTagSupport类
  2. 做一个标签的描述文件tld文件,在这个文件中来对标签进行描述
  3. 在jsp页面上使用自定义标签。

关于SimpleTag接口的方法描述

wpsB955.tmp

  • doTag方法它的作用:描述标签的功能 (会被自动调用)
  • setJspContext:它的参数是JspContext,它的作用是将页面的pageContext对象传递到标签类中。(很大用途,用于获取其他八大对象)
  • setJspBody:将标签体的内容缓存到内存对象中,而参数JspFragment 相当于标签体内容。
  • getParent  setParent 将标签的父标签引入。(基本不用)

 

下面是一个自定义标签类:(用于是一个多次打印标签体内容的 java 类)

复制代码
package online.mytag;

import java.io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class PrintTag extends SimpleTagSupport {
    
    private int count;
    
    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    @Override
    public void doTag() throws JspException, IOException {
        //创建一个流,用于接收标签体的内容
        StringWriter sw = new StringWriter();
        getJspBody().invoke(sw);
        String str = sw.toString();
        JspWriter out = getJspContext().getOut();
        for (int i = 0; i < count; i++) {
            out.write(str);
        }
    }
}
复制代码

 

下面是一个自定义标签类:(用于获取浏览器端的 ip 地址)

复制代码
package online.mytag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;


public class IpTag extends SimpleTagSupport {

    /**
     * 向浏览器输出浏览器的ip
     */
    @Override
    public void doTag() throws JspException, IOException {
        String  ip = (String)((PageContext)(getJspContext())).getRequest().getRemoteAddr();
        getJspContext().getOut().write(ip);
    }
}
复制代码

上面两个标签实现类对应的 .tld 文件:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
    <tlib-version>1.0</tlib-version>
    <short-name>my</short-name>    <!-- 这里是使用该标签时taglib的refer属性值:<%@taglib uri="online.mytag.IpTag" prefix="my"%> -->
    <uri>http://java.sun.com/jsp/jstl/mytag</uri>   <!-- 这里是使用该标签时taglib的uri属性 -->
    <tag>    <!-- 这里的每一个<tag>都指定一个标签java类 -->
        <description>输出浏览器端的ip</description>  <!-- 一些描述,也就是注释 -->
        <name>getIp</name>          <!-- 使用该标签类时的标签名 -->
        <tag-class>online.mytag.IpTag</tag-class>     <!-- 标签类的全类名 -->
        <body-content>empty</body-content>       <!-- 这个属性说明是否有标签体 -->
    </tag>

    <tag>
        <description>根据标签属性值循环输出标签体</description>
        <name>print</name>
        <tag-class>online.mytag.PrintTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>         <!-- 指的是标签类中的字段,有几个字段,就有几个attribute标签 -->
            <description>循环的次数</description>
            <name>count</name>         <!-- 使用该标签时,标签中的属性名 -->
            <required>true</required>     <!-- 指明该属性是否是必需的 -->
            <rtexprvalue>true</rtexprvalue>    <!-- 指明该属性是否支持el表达式 -->
        </attribute>
    </tag>
</taglib>


web.xml 关联 .tld文件
<taglib>
	<taglib-uri>mytags</taglib-uri>
	<taglib-location>/WEB-INF/jsp/mytaglib.tld</taglib-location>
</taglib>
复制代码

在jsp页面中使用自定义标签:

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="online.mytag.IpTag" prefix="my"%>
<!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>
    <my:getIp/>
    
    <my:print count="2">
        hello tag
    </my:print>
</body>
</html>
复制代码

画个图说明下tag标签下的子标签:(注意:attribute对应的字段必须在标签类中提供对应的get/set方法

1

 


总结下自定义标签:

      我们使用的是简单标签,也就是通过实现SimpleTag或继承SimpleTagSupport来实现自定义标签。

基本步骤:

1.创建标签类 implements SimpleTag   extends SimpleTagSupport类

  • JspContext 它就代表的是jsp页面上的pageContext对象
  • JspFragment 它就代表的是标签体中的内容,通过它的invoke方法可以将标签体的内容指定到invoke方法参数的输出流输出,如果为null,默认是当前jsp页面关联的out对象。

2.在WEB-INF/创建一个tld文件

  • 使用<tag>来描述标签
  • 使用<tag>下的<name>来定义标签名称
  • 使用<tag>下的<tag-class>来定义标签类
  • 使用<tag>下的<body-content>来描述标签体中是否有内容,可以使用的值有两个
  • empty  scriptless
  • 使用<tag>下的<attribute>来描述属性,但是必须在标签类中提供对应的get/set方法
  • 使用<attribute>下的<name>来声明属性名称
  • 使用<attribute>下的<required>来声明属性是否必须存在
  • 使用<attribute>下的<rtexprvalue>来声明属性是否可以使用el表达式

注意:

  • 在tld文件创建时,要选择2.0以上版本,并且tld文件创建后有缺陷,需要手动将schemaLocation中第一个值复制一份放到xsd文件前

(xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd")

3.在jsp页面上使用taglib导入标签

  • 使用标签必须使用taglib先导入标签才能用。

以上是关于自定义标签的主要内容,如果未能解决你的问题,请参考以下文章

Android TabLayout ViewPager 不会在 backstack 上膨胀标签片段

VSCode自定义代码片段——CSS选择器

vscode自定义问题

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段——声明函数