The forty-eighth day of Java, Taglib of Jsp, detailed explanation of custom tags

theoretical knowledge


1. What is the essence of the label?

A custom tag is actually a Java class that implements a specific interface. It encapsulates some common functions and is replaced by the corresponding code at runtime; the biggest difference between it and JavaBean is that JavaBean has no default context (JspContext), but the tag have.

A custom tag consists of a tag handler and a tag description;

  • Tag handler: When a specific tag is encountered, the tag handler will tell the system what to do, and the class contains the java code to be executed
  • Label description: declares how to use this label
  • Tag: can have attributes and body, these attributes and body are optional, the simplest tag is neither attribute nor body

2. Label interface introduction

All JSP tags implement the javax.servlet.jsp.tagext.JspTag interface; the two direct subinterfaces of this interface are as follows:

  • SimpleTag ===> JSP2.0 newly added interface (hereinafter collectively referred to as simple tags)
  • Tag ===> It is a classic interface that must be implemented. It has a direct sub-interface which is IterationTag (hereinafter collectively referred to as traditional tags)

The Tag interface has a direct sub-interface IterationTag (hereinafter collectively referred to as traditional tags), which inherits the Tag interface;

The Tag interface has a direct subinterface TagSupport, which implements the Tag interface; (the TagSupport interface has a direct subinterface, BodyTagSupport; it allows tags with a body)

3. Basic theoretical knowledge of custom tag library

1. Custom tag library architecture

 2. Custom Tag Handler Component

 3. Basic concepts

  • Tag (Tag): Let the JSP page implement specific functions. Through the tag, the JSP web page can be made concise and easy to maintain. It is an XML element whose name and attributes are case sensitive.
  • Tag library (Tag library): A collection of tags with similar functions and logical interrelationships. The "prefix" of the same tag library is the same
  • Tag library description file (Tag Library Descriptor): It is an XML file that provides the mapping relationship between classes in the tag library and tag references in JSP. It is also a configuration file, similar to web.xm
  • Tag Handle Class: It is a Java class that directly or indirectly inherits the Tag interface, and may also implement Tag or its sub-interfaces. Through this class, the specific functions of JSP tags can be defined by themselves.

4. Label life cycle

  1. When the container creates a new label instance, set the page context of the label through setPageContext
  2. Use the setParent method to set the parent label of this label, if there is no previous nesting, set it to null
  3. The attribute of the tag is defined in the description file of the tag library
  4. Call the doStartTag method, which returns EVAL_BODY_INCLUDE and SKIP_BODY (EVAL_BODY_INCLUDE: Calculate the Body of the tag; SKIP_BODY: Do not calculate the Body of the tag)
  5. Call the doEndTag method, which returns EVAL_PAGE or SKIP_PAGE (EVAL_PAGE: the container will continue to calculate other parts of the jsp page at the end; SKIP_PAGE: the container will stop calculating other parts of the jsp page when the tag ends)
  6. Call the realse() method to release any resources occupied by the label program

The meaning of each function and keyword in the life cycle:

1.doStartTag()

When encountering the start tag of a custom tag, call the method of the tag processing class, and the meaning of the return value is as follows

  • EVAL_ BODY_INCLUDE (indicates that the tag body is to be executed, and the execution result is placed in the current output stream)
  • SKP_BODY (do not execute tag body)

2.doEndTag()

When encountering the end tag of a custom tag, call the method of the tag processing class; the return value and its meaning are as follows:

  • EVAL_PAGE: The remaining content of the JSP page will continue to execute
  • SKIP_PAGE: The remaining content of the Jsp page is not executed

3.doAfterBody()

It is a method added to the IterationTag interface, which is called after the tag body is executed. If there is no tag body, this method will not be called. The return value of this method and its meaning are as follows:

  • SKIP_BODY: Skip the tag body
  • EVAL_BODY_AGAIN: repeated execution of the tag body

4.setBodyContent()

It is the method of setting the bodyContent property in the BodyTag interface, so as to obtain the content of the tag body later; it is only executed when doStartTag() returns EVAL_BODY _BUFFERED

5. Steps to create a custom label

  1. Create a label processing class
  2. Write and deploy tag library description (TLD) files
  3. Configure tag library information in the web.xml file
  4. Using tag library in JSP file

6. Tag library description (TLD) file

(1) Function

The role of the tag library description (TLD) file is to find the corresponding tag processing class by the tag

(2) Precautions

The extension of the tag library description (TLD) file is tld, which is an xml type file. It is usually placed in META INF or WEB-INF or its subdirectory, but it cannot be stored in the WEB\INF\classes directory and WEB-INF\Iib directory middle

(3) Main mark

url tag ===> Find the corresponding processing class for each custom tag. uri contains a string, which is used by the container to locate the TLD file. In the TLD file, the names of all tag processing classes in the tag library can be found, and can also be set in web.xml

description tag ===> description information

display-name tag ===> name to be displayed by the visualizer (optional)

tlib-version tag ===> version of this tag library

The shortname tag ===> the "prefix" of the tag; used to identify the tag library, the prefix of the same tag library is the same

tag mark ===> label

The tag tag can contain the following sub-tags

<name>标签名</name>

<tag-class>package name.tag processing class</tag-class>

<attibute>...</attribute>: You can set the attribute name, whether it is required, whether the attribute value is an expression at runtime, etc.

<body-content>..</body-content>

The <body-content/> tag body can have 4 values:

  • empty (no label body)
  • JSP (by default, the tag body can contain JSP code)
  • scriptless (the tag body can contain EL, JSP standard actions, but no scripts)
  • tagdependent (the tag body is handled by the tag)

(4) The calling process of the custom label

  1. The web container obtains the value of the uri attribute in the taglib instruction according to the tag prefix
  2. The web container finds the corresponding <taglib> element in web.xml according to the uri attribute
  3. Obtain the value of the corresponding <taglib-location> element from the <taglib> element
  4. The web container finds the corresponding td file from the WEB-INF/ directory according to the value of the <taglib-location> element
  5. Find the <tag> element corresponding to the tag name from the tld file
  6. Get the value of the corresponding <tag-class> element from the <tag> element
  7. The web container creates the corresponding tag processing class instance according to the value of the <tag-class> element
  8. The web container calls the doStartTag/doEndTag method of this instance to complete the corresponding processing

Technical combat


1. Develop custom tags based on the Tag interface (no attribute, no tag body)

1. Create a label processing class

package taglib;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyTaglib implements Tag {

    private PageContext pageContext;
    private Tag parent;

    public MyTaglib() {
        super();
    }

    @Override
    public void setPageContext(PageContext pageContext) {
        this.pageContext = pageContext;
    }

    @Override
    public void setParent(Tag tag) {
        this.parent = tag;
    }

    @Override
    public Tag getParent() {
        return this.parent;
    }

    @Override
    public int doStartTag() throws JspException {
        //返回 SKIP_BODY,表示不计算标签体
        return SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();// 获取当前时间
            pageContext.getOut().write(sdf.format(date));
        } catch (IOException e) {
            throw new JspTagException(e.getMessage());
        }
        return EVAL_PAGE;
    }

    @Override
    public void release() {

    }
}

2. Write and deploy tag library description (TLD) files

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>学习如何使用 Tag 接口</description>
    <tlib-version>1.0</tlib-version>
    <!--该属性是设置该标签库下所有标签的前缀-->
    <short-name>tools</short-name>
    <!--该属性是设置该标签库的唯一 url-->
    <uri>/learnTag</uri>



    <!--为标签库添加 标签-->
    <tag>
        <description>基于 Tag 接口的自定义标签</description>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTime</name>
        <!--指明标签处理类的位置-->
        <tag-class>taglib.MyTaglib</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>
</taglib>

3. Configure the tag library information in the web.xml file

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置taglib-->
  <taglib>
    <!--设置标签库唯一 url ;这里的 url 必须与 tld 文件中的 url 一致-->
    <taglib-uri>/learnTag</taglib-uri>
    <!--指明 tld 标签库描述文件的位置-->
    <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
  </taglib>
  <!---->
</web-app>

4. Use the tag library in the JSP file

<!--配置 taglib 标签库的前缀与 url,这里的前缀与 url 必须与 tld 文件的一致-->
<%@ taglib prefix="tools" uri="/learnTag" %>
<html>
<body>
    <!--采取 标签库名:标签名 格式使用指定标签库下的指定标签-->
    <tools:showTime/>
</body>
</html>

2. Develop custom tags based on the TagSupport abstract class (no attribute, no tag body)

1. Create a label processing class

Note: When inheriting the TagSupport abstract class to implement custom tags, you only need to implement the methods you need to use, that is, you don’t need to implement any unnecessary methods

package tagSupport;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyTaglibSupport extends TagSupport {

    @Override
    public int doEndTag() throws JspException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();// 获取当前时间
            pageContext.getOut().write(sdf.format(date));
        } catch (IOException e) {
            throw new JspTagException(e.getMessage());
        }
        return EVAL_PAGE;
    }
}

2. Write and deploy tag library description (TLD) files

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>学习如何使用 Tag 接口</description>
    <tlib-version>1.0</tlib-version>
    <!--该属性是设置该标签库下所有标签的前缀-->
    <short-name>tools</short-name>
    <!--该属性是设置该标签库的唯一 url-->
    <uri>/learnTag</uri>



    <!--为标签库添加 标签-->
    <tag>
        <description>基于 Tag 接口的自定义标签</description>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTime</name>
        <!--指明标签处理类的位置-->
        <tag-class>taglib.MyTaglib</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <!--为标签库添加新的标签-->
    <tag>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTimeV2</name>
        <!--指明标签处理类的位置-->
        <tag-class>tagSupport.MyTaglibSupport</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>
</taglib>

3. Configure the tag library information in the web.xml file

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置taglib-->
  <taglib>
    <!--设置标签库唯一 url ;这里的 url 必须与 tld 文件中的 url 一致-->
    <taglib-uri>/learnTag</taglib-uri>
    <!--指明 tld 标签库描述文件的位置-->
    <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
  </taglib>
  <!---->
</web-app>

4. Use the tag library in the JSP file

<%@ taglib prefix="tools" uri="/learnTag" %>
<html>
<body>
    <!--采取 标签库名:标签名 指明要使用的标签-->
    <tools:showTimeV2/>
</body>
</html>

3. Develop custom tags based on the TagSupport abstract class (with attributes, without tag body)

1. Create a label processing class

package tagSupport;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyTaglibSupportAttr extends TagSupport {

    // 对于有属性的标签,需要在标签处理类中设置同名的属性,并为属性设置 get 和 set 方法
    private String country;
    private String city;

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public int doEndTag() throws JspException {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat();
            sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();// 获取当前时间
            pageContext.getOut().write(country + "-" + city + ": " + sdf.format(date));
        } catch (IOException e) {
            throw new JspTagException(e.getMessage());
        }
        return EVAL_PAGE;
    }
}

2. Write and deploy tag library description (TLD) files

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>学习如何使用 Tag 接口</description>
    <tlib-version>1.0</tlib-version>
    <!--该属性是设置该标签库下所有标签的前缀-->
    <short-name>tools</short-name>
    <!--该属性是设置该标签库的唯一 url-->
    <uri>/learnTag</uri>



    <!--为标签库添加 标签-->
    <tag>
        <description>基于 Tag 接口的自定义标签</description>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTime</name>
        <!--指明标签处理类的位置-->
        <tag-class>taglib.MyTaglib</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <!--为标签库添加新的标签-->
    <tag>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTimeV2</name>
        <!--指明标签处理类的位置-->
        <tag-class>tagSupport.MyTaglibSupport</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>showTimeV3</name>
        <tag-class>tagSupport.MyTaglibSupportAttr</tag-class>
        <body-content>empty</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>country</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>city</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

3. Configure the tag library information in the web.xml file

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置taglib-->
  <taglib>
    <!--设置标签库唯一 url ;这里的 url 必须与 tld 文件中的 url 一致-->
    <taglib-uri>/learnTag</taglib-uri>
    <!--指明 tld 标签库描述文件的位置-->
    <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
  </taglib>
  <!---->
</web-app>

4. Use the tag library in the JSP file

<%@ taglib prefix="tools" uri="/learnTag" %>
<html>
<body>
    <!--采取 标签库名:标签名 指明要使用的标签-->
    <tools:showTimeV3 country="china" city="shi_jia_zhuang"/>
</body>
</html>

4. Develop custom tags based on the BodyTagSupport abstract class (with attributes and tag body)

1. Precautions

A Tag with a body must implement the javax.servlet.jsp.tagext.BodyTag interface, and the BodyTag interface defines methods for processing tags;

2. The life cycle of a tag with a tag body:

  1. When the container creates a new label instance, set the context of the label page through setPageContext
  2. Use the setParent method to set the parent label of this label, if there is no previous nesting, set it to null
  3. Set the attributes of the label, defined in the label's description file
  4. Call the doStartTag method, if EVAL_BODY_INCLUDE is returned, the BODY of the tag will be calculated; if SKIP_BODY is returned, the Body of the tag will not be calculated
  5. Call setBodyContent to set the current BodyContent
  6. Call doInitBody, if initialization is required when calculating BodyContent, do it in this method
  7. Call doAfterBody after calculating BodyTag each time, if EVAL_BODY_TAG is returned, it means continue to calculate bodytag once, and do not execute step 8 until SKIP_BODY is returned
  8. When calling the doEndTag method, if EVAL_PAGE is returned, the container will continue to calculate other parts of the jsp page after the tag ends; if SKIP_PAGE is returned, the container will stop calculating other parts of the jsp page when the tag ends
  9. Call the realse() method to release any resources occupied by the label program

3.BodyTagSupport class

① BodyTagSupport inherits from the TagSupport class and implements the BodyTag interface

② This class adds a member variable BodyContent; the BodyContent class is a subclass of JspWriter, which is mainly used to access the tag body and save the tag body processing results

③ This class adds setBodyContent(BodyContent b), doInitBody(), doAfterBody() methods

4. Analyze the steps to modify the tag body

  1. Inherit the BodyTagSupport class or implement the BodyTag interface 
  2. doStartTag() returns EVAL_BODY_BUFFERED (indicating that the tag body is to be executed, and the execution result is placed in the current output stream)
  3. Process the tag body in the doAfterBody() method (call getBodyContent(), related methods of BodyContent, get the tag body content, and store the program processing result in the output stream

As can be seen from the above, to obtain and modify the content of the tag body, an important class is needed—BodyContent, which has two important methods

String getString(): returns the content of the tag body as a string

public JspWriter getEnclosingWriter(): get the encapsulated JspWriter object

1. Create a label processing class

package tagSupport;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyTaglibSupportAttrBody extends BodyTagSupport {

    // 对于有属性的标签,需要在标签处理类中设置同名的属性,并为属性设置 get 和 set 方法
    private String country;
    private String city;

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public int doStartTag() throws JspException {
        return EVAL_BODY_BUFFERED;
    }

    @Override
    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }

    @Override
    public void doInitBody() throws JspException {
        super.doInitBody();
    }

    @Override
    public int doAfterBody() throws JspException {

        JspWriter out = bodyContent.getEnclosingWriter();
        try {
            out.println(bodyContent.getString() + country + "-" +city + "<br/>");
        } catch (IOException e) {
            e.printStackTrace();
        }
        bodyContent.clearBody();
        return super.doAfterBody();
    }
}


2. Write and deploy tag library description (TLD) files

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>学习如何使用 Tag 接口</description>
    <tlib-version>1.0</tlib-version>
    <!--该属性是设置该标签库下所有标签的前缀-->
    <short-name>tools</short-name>
    <!--该属性是设置该标签库的唯一 url-->
    <uri>/learnTag</uri>



    <!--为标签库添加 标签-->
    <tag>
        <description>基于 Tag 接口的自定义标签</description>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTime</name>
        <!--指明标签处理类的位置-->
        <tag-class>taglib.MyTaglib</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <!--为标签库添加新的标签-->
    <tag>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTimeV2</name>
        <!--指明标签处理类的位置-->
        <tag-class>tagSupport.MyTaglibSupport</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>showTimeV3</name>
        <tag-class>tagSupport.MyTaglibSupportAttr</tag-class>
        <body-content>empty</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>country</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>city</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>showTimeV4</name>
        <tag-class>tagSupport.MyTaglibSupportAttrBody</tag-class>
        <body-content>JSP</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>country</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>city</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

3. Configure the tag library information in the web.xml file

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置taglib-->
  <taglib>
    <!--设置标签库唯一 url ;这里的 url 必须与 tld 文件中的 url 一致-->
    <taglib-uri>/learnTag</taglib-uri>
    <!--指明 tld 标签库描述文件的位置-->
    <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
  </taglib>
  <!---->
</web-app>

4. Use the tag library in the JSP file

<%@ taglib prefix="tools" uri="/learnTag" %>
<html>
<body>
    <!--采取 标签库名:标签名 指明要使用的标签-->
    <tools:showTimeV4 country="china" city="shi_jia_zhuang">
        My home is in :
    </tools:showTimeV4>
</body>
</html>

5. Develop custom tags based on the SimpleTag interface (with attributes, without tag body)

SimpleTag is a new type of tag added to the JSP2.0 specification, which simplifies the complex operations in traditional tag development;

A new API for creating self-made tags has been added to JSP 2.0, and javax.servlet.jsp.tagext.SimpleTag defines an interface for implementing simple tags. Different from the existing interfaces in JSP 1.2, the SimpleTag interface does not use the doStartTag() and doEndTag() methods, but provides a simple doTag() method. This method is used only once when calling this marker. All logic, loops, and evaluation of tag bodies that need to be implemented in a self-made tag are implemented in this method.

From this aspect, SimpleTag and IterationTag can achieve the same effect. But SimpleTag's methods and processing cycle are much simpler. There are also seJspBody() and getJspBody() methods used to set JSP content in SimpleTag. The Web container will use the setJspBody() method to define a JspFragment object representing the JSP content. The program implementing the SimpleTag tag can call the getJspBody().invoke() method as many times as needed in the doTag method to process the JSP content

return type method name method description
void doTag() The method of executing business processing, all logic processing is carried out here
static JspTag findAncestorWithClass(JspTag from, Class klass) finds the closest instance of the given class type to the given instance
protected JspFragment getJspBody() Return the body passed in by the container through setJspBody
protected JspContext getJspContext() Returns the page context passed in by the container through setJspContext
JspTag getParent() For collaborative purposes, returns the parent of this tag
void setJspBody(JspFragment jspBody) Store the provided JspFragment
void setJspContext(JspContext pc) Store the provided JSP context in the private jspContext field
void setParent(JspTag parent) Sets the parent of this label, for collaboration

SimpleTagSupport life cycle

  1. Each time a tag is encountered, the container constructs an instance of SimpleTag, and this constructor has no parameters. Like traditional tags, SimpleTag cannot be buffered, so it cannot be reused, and a new instance must be constructed each time
  2. After calling the constructor, call the setJspContext() and setParent() methods, and only call the setParent method when the label is within another label
  3. The container calls the setter method of each property to set the value of those properties
  4. If there is a body, then use the setJspBody method to set the tag body of this tag.
  5. The container calls the doTag method, all tag logic, iteration and Body calculations are in this method
  6. When the doTag method returns, all parameters are locked
     

1. Create a label processing class

package simpleTablib;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

public class MySimpleTaglib extends SimpleTagSupport {

    private String userName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Override
    public void doTag() throws JspException, IOException {
        getJspContext().getOut().println("Your name is " + userName);
    }
}

2. Write and deploy tag library description (TLD) files

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>学习如何使用 Tag 接口</description>
    <tlib-version>1.0</tlib-version>
    <!--该属性是设置该标签库下所有标签的前缀-->
    <short-name>tools</short-name>
    <!--该属性是设置该标签库的唯一 url-->
    <uri>/learnTag</uri>



    <!--为标签库添加 标签-->
    <tag>
        <description>基于 Tag 接口的自定义标签</description>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTime</name>
        <!--指明标签处理类的位置-->
        <tag-class>taglib.MyTaglib</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <!--为标签库添加新的标签-->
    <tag>
        <!--为本标签设置所在标签库下唯一标签名-->
        <name>showTimeV2</name>
        <!--指明标签处理类的位置-->
        <tag-class>tagSupport.MyTaglibSupport</tag-class>
        <!--因为没有标签体所以设为 empty-->
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>showTimeV3</name>
        <tag-class>tagSupport.MyTaglibSupportAttr</tag-class>
        <body-content>empty</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>country</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>city</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>showTimeV4</name>
        <tag-class>tagSupport.MyTaglibSupportAttrBody</tag-class>
        <body-content>JSP</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>country</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>city</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>showName</name>
        <tag-class>simpleTablib.MySimpleTaglib</tag-class>
        <body-content>empty</body-content>

        <attribute>
            <!--设置属性名,必须与标签处理类中的属性名一致-->
            <name>userName</name>
            <!--设置该属性是否必须-->
            <required>true</required>
            <!--设置是否支持 EL 表达式赋值-->
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

3. Configure the tag library information in the web.xml file

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置taglib-->
  <taglib>
    <!--设置标签库唯一 url ;这里的 url 必须与 tld 文件中的 url 一致-->
    <taglib-uri>/learnTag</taglib-uri>
    <!--指明 tld 标签库描述文件的位置-->
    <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>
  </taglib>
  <!---->
</web-app>

4. Use the tag library in the JSP file

<%@ taglib prefix="tools" uri="/learnTag" %>
<html>
<body>
    <!--采取 标签库名:标签名 指明要使用的标签-->
    <tools:showName userName="John"/>
</body>
</html>

Guess you like

Origin blog.csdn.net/ITlanyue/article/details/118674805