• Jsp学习(五)


    自定义标签

    1、标签类型

    • Has body

        有标签体,必须位于开始标记和结束标记之间
        内容包括:自定义标记或核心标记,HTML 文本,标签依赖的主体内容
        比如:<html:submit> OK </html:submit>

    • Has no body

        没有标签体
        比如<html:errors />

    2、自定义标签的步骤

    • 创建一个类,用来对标签的行为进行控制

        这个类 继承 javax.servlet.jsp.tagext.SimpleTagSupport 并重写 doTag() 方法

    •  创建标签库描述符 ( Tag Library Descriptor ):

        标签库描述符是个 XML 文件,一般被放在 WEB-INF 目录下即可
        标签库描述符 的扩展名不是 .xml 而是 .tld

    • 在页面上使用标签

        导入标签库:uri 用于指定tld 中<uri> 中的字符串值,prefix 用于指定标签的前缀,这个名称任意取

    <%@ taglib prefix = "m" uri = "http://www.ecut/tags"%>

        使用标签:其中tagPrefix 要与taglib 中的prefix 的值写一致,而tagName 就是tld 文件中<tag> 内部<name> 标签内部的字符串值

    <tagPrefix:tagName />

    3、测试案例

    • 不带属性、不带标签体 的自定义标签: HelloTag
    package ecut.tags;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    /*创建一个类,用来对标签的行为进行控制
    这个类 继承 javax.servlet.jsp.tagext.SimpleTagSupport 并重写 doTag() 方法*/
    public class HelloTag extends SimpleTagSupport {
    
        @Override
        public void doTag() throws JspException, IOException {
            
            JspContext jspContext = this.getJspContext();
            
            JspWriter out = jspContext.getOut();
            // 这个方法由容器调用。 所有标签逻辑,迭代,标签体的处理等都放在这个方法中。
            out.println( "<div style='border:1px solid blue;text-align:center;padding:5px 5px ;'>" );
            out.println( "hello" );
            out.println( "</div>" );
            
        }
    
    }

    标签库描述符m.tld

    <?xml version="1.0" encoding="UTF-8"?>
    
    <taglib 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"
        version="2.1">
        <!-- short-name建议所采用的简称(prefix),具体用那个简称以jsp页面中prefix为准 -->
        <!-- uri 唯一 -->
        <tlib-version>1.0</tlib-version>
        <short-name>m</short-name>
        <uri>http://www.ecut/tags</uri>
    
        <!-- 定义一个标签: 没有属性、不带标签体 -->
        <tag>
            <name>hello</name>
            <tag-class>ecut.tags.HelloTag</tag-class>
            <!-- 必须有body-content元素 -->
            <body-content>empty</body-content>
        </tag>
    </taglib>

    <tag>各子元素的意义与作用
    <description> 可选,标签的描述信息
    <name> 必需,定义JSP页面引用的标签名称(标签后缀)
    <tag-class> 必需,标识实现标签处理类的完全限定名(含包名的类名)
    <body-content> 必需,告诉容器如何处理标签开始和结束之间的内容
    <body-content> 取值可以是empty 、scriptless 、tagdependent 、JSP
      empty : 不允许任何内容出现在标签体内(用于定义没有标签体的标签)
      scriptless : 允许标签中有JSP 内容,但不能包含<% ... %> 和<%= ... %> 之类
      tagdependent : 允许此标签像其主体一样有任何类型的内容
        » 但是这些内容根本不会被处理,并会完全忽略
        » 由标签处理类开发人员来决定访问这些内容,并对其进行处理
        » 比如其中包含一个允许JSP 开发人员执行的SQL 语句
    JSP : 允许在标签体中放置JSP 内容

    在index.jsp上使用标签

    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%>
    <!-- 导入标签库 -->
    <%@ taglib prefix = "m" uri = "http://www.ecut/tags"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>自定义标签</title> </head> <body> <!--使用标签 --> <m:hello></m:hello> </body> </html>
    • 带有属性的自定义标签: TableTag
    package ecut.tags;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class TableTag extends SimpleTagSupport {
        //getXxx()方法要和标签的属性名一致
        private int rows ;
        private int columns ;
        private String className ;
    
        @Override
        public void doTag() throws JspException, IOException {
            System.out.println( "rows : " + rows  );
            System.out.println( "columns : " + columns  );
            System.out.println( "className : " + className  );
            
            JspContext jspContext = this.getJspContext();
            
            JspWriter out = jspContext.getOut();
            
            out.println( "<table class='" + className + "'>" );
            
            for( int i = 0 ; i < rows ; i++ ){
                out.println( "<tr>" );
                
                for( int j = 0 ; j < columns ; j++){
                    out.println( "<td>" );
                    out.println( i + " , " + j );
                    out.println( "</td>" );
                }
                
                out.println( "</tr>" );
            }
            
            out.println( "</table>" );
            
        }
    
        public int getRows() {
            return rows;
        }
    
        public void setRows(int rows) {
            this.rows = rows;
        }
    
        public int getColumns() {
            return columns;
        }
    
        public void setColumns(int columns) {
            this.columns = columns;
        }
    
        public String getClassName() {
            return className;
        }
    
        public void setClassName(String className) {
            this.className = className;
        }
    
    }

    如果自定义标签包含属性,那么对应的标签类中也要有相应的属性,getXxx名称还要完全相同,每个属性都必须有对应的getter 和setter 方法

    <?xml version="1.0" encoding="UTF-8"?>
    
    <taglib 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"
        version="2.1">
        <!-- short-name建议所采用的简称(prefix),具体用那个简称以jsp页面中prefix为准 -->
        <!-- uri 唯一 -->
        <tlib-version>1.0</tlib-version>
        <short-name>m</short-name>
        <uri>http://www.ecut/tags</uri>
      <!-- 定义一个带有属性不带标签体的标签 -->
        <tag>
            <name>table</name>
            <tag-class>ecut.tags.TableTag</tag-class>
            <body-content>empty</body-content>
    
            <!-- 定义标签的属性 -->
            <attribute>
                <name>rows</name>
                <!-- 是否必填 -->
                <required>true</required>
                <!--run time expression value 是否可以接受一个运行时值(动态的值) -->
                <rtexprvalue>true</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>columns</name>
                <required>true</required>
                <rtexprvalue>true</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>className</name>
                <required>false</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
    
        </tag>
    </taglib>

    <attribute> 标签中各个子元素的意义及作用
    <name> 必需,定义属性名称
      严格区分大小写,与Tag Handler Class 里的getter 和setter 对应
    <required> 可选,指定是必须始终提供该属性
      false 是默认值,表示并不是一定要提供该属性
      true 是可选值之一,表示必须始终提供该属性
    <rtexprvalue> 可选,Runtime Expression Value指出属性值是一个动态确定的值还是一个固定的值
      true 表示可以接受运行时的表达式的值,表达式可以是 JSP 表达式,也可以是 EL 表达式
           false 表示不可以接受表达式的值,因此在使用时必须显式指定具体的值

    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%> <!-- 导入标签库 -->
    <%@ taglib prefix = "m" uri = "http://www.ecut/tags"%>
    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>自定义标签</title> <style type="text/css"> .tab { border: 1px solid blue; width: 100%; margin: 20px auto; border-spacing: 10px; } .tab td { border: 1px solid green; height: 30px; text-align: center; vertical-align: middle; } </style> </head> <body> <!--使用标签 --> <m:table rows="3" columns="4" className="tab"></m:table> <% int r = 6 ; pageContext.setAttribute( "c" , 3 ) ; // page scope 中存入一个名称是 c 的值 %> <m:table rows="<%= r %>" columns="${ c }" className="tab"></m:table>
    </body>
    </html>
     
    • 有属性、有身体 的标签 : ForTag
    package ecut.tags;
    
    import java.io.IOException;
    
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    public class ForTag extends SimpleTagSupport {
        
        private int begin ;
        private int step ;
        private int end ;
        
        private String var ;
    
        @Override
        public void doTag() throws JspException, IOException {
            
            JspContext jspContext = this.getJspContext();
            
            //JspWriter out = jspContext.getOut();
            
            JspFragment fragment = this.getJspBody(); // 获得 标签体 对应的 对象
            
            for( int i = begin ; i <= end ; i += step ){
                // < var , i > 
                System.out.println( var + " , " + i );
                // 将每次循环中的 i 的值 放入到 page scope ( JspContext 是 PageContext 类的父类 )
                jspContext.setAttribute( var , i ) ; // jspContext.setAttribute( "counter" , i );
                // 执行 JSP 代码片段 ( 标签体 ),如果是null,则会自动将getOut()返回的值传入invoke方法中
                fragment.invoke( null ); 
            }
            
        }
    
        public int getBegin() {
            return begin;
        }
    
        public void setBegin(int begin) {
            this.begin = begin;
        }
    
        public int getStep() {
            return step;
        }
    
        public void setStep(int step) {
            this.step = step;
        }
    
        public int getEnd() {
            return end;
        }
    
        public void setEnd(int end) {
            this.end = end;
        }
    
        public String getVar() {
            return var;
        }
    
        public void setVar(String var) {
            this.var = var;
        }
    
    }
    <?xml version="1.0" encoding="UTF-8"?>
    
    <taglib 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"
        version="2.1">
        <!-- short-name建议所采用的简称(prefix),具体用那个简称以jsp页面中prefix为准 -->
        <!-- uri 唯一 -->
        <tlib-version>1.0</tlib-version>
        <short-name>m</short-name>
        <uri>http://www.ecut/tags</uri>
       <!-- 定义一个带有属性、带有标签体的标签 -->
        <tag>
            <name>for</name>
            <tag-class>ecut.tags.ForTag</tag-class>
            <body-content>scriptless</body-content>
    
            <attribute>
                <name>begin</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>step</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>end</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
    
            <attribute>
                <name>var</name>
                <required>true</required>
                <rtexprvalue>false</rtexprvalue>
            </attribute>
    
        </tag>
    
    </taglib>
    <%@ page language = "java" pageEncoding = "UTF-8" %>
    <%@ page contentType = "text/html; charset= UTF-8"%> <!-- 导入标签库 -->
    <%@ taglib prefix = "m" uri = "http://www.ecut/tags"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>自定义标签</title> </head> <body>

      <
    m:for begin="10" step="10" end="100" var="counter"> <div>${ counter }</div> </m:for>
    </body>
    </html>

    转载请于明显处标明出处

    https://www.cnblogs.com/AmyZheng/p/9187672.html

  • 相关阅读:
    深入理解JS中的变量及变量作用域
    浏览器加载、解析、渲染的过程
    gerrit和git
    宽高等比缩放
    常见的网站性能优化手段
    JS实现数组去重(重复的元素只保留一个)
    重构与回流
    APP开放接口API安全性——Token令牌Sign签名的设计与实现
    索引原理-btree索引与hash索引的区别
    从四个维度谈谈如何做好团队管理
  • 原文地址:https://www.cnblogs.com/AmyZheng/p/9187672.html
Copyright © 2020-2023  润新知