• jsp 简单标签开发


    实现simpleTag接口的标签通常称为是简单标签,简单标签一共定义了5个方法

    setJspContext方法
    setParent方法
    getParent方法
    setJspBody方法
    doTag方法,简单标签就是使用这个方法可以完成所有的业务逻辑
    

    SimpleTag方法介绍

    setJspContext方法
            用于把父标签处理器对象传递给标签处理器对象
    setParent方法
            用于把父标签处理器对象传递给当前标签处理器对象
    getParent方法
            用于获得当前标签的父标签处理器对象
    setJspBody方法
            用于把代表标签体的JspFragment对象传递给标签处理器对象
    doTag方法
            用于完成所有的标签逻辑,包括输出,迭代,修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况
    

    SimpleTag接口的执行顺序

    当WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
    WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下web容器才会调用这个方法
    如果调用标签时,设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象,如果标签的属性值是EL表达式或者脚本表达式,则WEB容器首先计算表达式的值,然后再把值传给标签处理器对象。
    如果简单的标签标签体,web容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来
    执行标签时,web容器调用标签处理器的doTag()方法,开发人员在方法体内部同步操作jspFragment对象,就可以实现是否执行,迭代,修改标签体的目的。
    

    简单标签开发

    SUN公司针对SimpleTag接口提供了一个实现类,SimpleTagSupport,SimpleTagSupport类中实现了SimpleTag接口的所有方法,因此我们可以编写一个类继承SimpleTagSupport类然后,根据业务需要
    在重写doTag方法。
    

    控制JSP页面某一部分是否执行

        编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面不调用jspFrament.invoke方法即可
        
    ​
    /**
     * simpleTagSupport实现了SimpleTag接口
     * SimpleTagOne继承了SimpleTagSupport
     * @author ssgao
     *
     */
    public class SimpleTagOne extends SimpleTagSupport{
        /**
         * 简单标签使用这个方法就可以完成所有业务逻辑
         * javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 
         * 重写doTag方法,控制标签体是否执行
         */
        @Override
        public void doTag() throws JspException, IOException {
    ​
            //得到代表JSp标签提的JspFragment
            JspFragment jspFragment=this.getJspBody();
            
            //得到Jsp页面的PageContext对象
            PageContext pageContext= (PageContext) this.getJspContext();
            //调用JspWriter将 标签体内容输出到浏览器
            JspWriter jspWriter=pageContext.getOut();
            jspWriter.write("自定义标签提");
            
            //将标签体的内容输出到浏览器
            jspFragment.invoke(jspWriter);
            //如果不需要输出
            //jspFragment.invoke(null);
        
    
    在WEB-INF目录下新建xxtld文件添加标签处理类描述
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
    <taglib>
       <!-- taglib标签库的版本号 -->
      <tlib-version>1.0</tlib-version>
      <jsp-version>jsp-version</jsp-version>
      <short-name>short-name</short-name>
      
      <!--   
                   为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/simpletag ,
                  在Jsp页面中引用标签库时,需要通过uri找到标签库
        在Jsp页面中就要这样引入标签库:<%@taglib uri="/simpletag" prefix="gacl"%>
       -->
      <uri>/simpletag</uri>
      <!-- 
        一个标签库 中包含多个自定义标签,每个自定义标签使用一个tag标记来描述
        一个tag标记对应一个自定义标签
      -->
      <tag>
        <!-- 
        为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类的
        通过demo1就能找到对应的me.gacl.web.simpletag.SimpleTagDemo1类
        -->
        <name>simple</name>
        <!-- 标签对应的处理器类-->
        <tag-class>simple.tag.SimpleTagOne</tag-class>
        
        <!--    
            tld文件中有四种标签体类型 :empty  JSP  scriptless  tagdepentend  
            在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
            在传统标签中标签体body-content的值只允许是empty和JSP
            如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
            例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
            <gacl:sql>SELECT * FROM USER</gacl:sql>
            在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可 
        -->
        <body-content>scriptless</body-content>
      </tag>
    </taglib>
    在JSP页面中导入并使用自定义标签   
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     <%@ taglib uri="/simpletag" prefix="gs" %>
    <!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>
    ​
       <gs:simple>
        我的宝贝是笑笑!
    </gs:simple>
    ​
    </body>
    </html>
    

    控制JSP页面内容重复执行

    编写一个类继承SimpleTagSupport,然后在重写doTag方法,在doTag方法里面重复调用jspFrament.invoke方法即可
    package simple.tag;
    ​
    import java.io.IOException;
    ​
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    ​
    /**
     * simpleTagSupport实现了SimpleTag接口
     * SimpleTagOne继承了SimpleTagSupport
     * @author ssgao
     *
     */
    public class SimpleTagOne extends SimpleTagSupport{
    ​
        /**
         * 简单标签使用这个方法就可以完成所有业务逻辑
         * javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 
         * 重写doTag方法,控制标签体是否执行
         */
        @Override
        public void doTag() throws JspException, IOException {
    ​
            //得到jsp标签体的JspFragment
            JspFragment jspFragment = this.getJspBody();
            for(int i=0;i<5;i++){
                //将标签体的内容输出到浏览器
                jspFragment.invoke(null);
            }
        }
    }
    在WEB-INF目录下添加tld文件对标签处理类的表述
     <tag>
        <name>simple</name>
        <tag-class>simple.tag.SimpleTagOne</tag-class>
        <body-content>scriptless</body-content>
      </tag>
    在JSP页面中导入并使用自定义标签   
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     <%@ taglib uri="/simpletag" prefix="gs" %>
    <!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>
    ​
    <gs:simple>
        <div style="height:10px; background-color:red;">ssgao</div>
    </gs:simple>
    ​
    </body>
    </html>
    修改JSP页面内容输出
    编写一个类继承SimpleTagSupport,然后在重写doTag方法,在doTag方法里面重复调用jspFrament.invoke方法时,让执行结果写到一个自定义的缓冲中即可,然后开发人员可以取出缓冲的数据进行修改。
    package simple.tag;
    ​
    import java.io.IOException;
    import java.io.StringWriter;
    ​
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.JspFragment;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    ​
    /**
     * simpleTagSupport实现了SimpleTag接口
     * SimpleTagOne继承了SimpleTagSupport
     * @author ssgao
     *
     */
    public class SimpleTagOne extends SimpleTagSupport{
    ​
        /**
         * 简单标签使用这个方法就可以完成所有业务逻辑
         * javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 
         * 重写doTag方法,控制标签体里面的内容,将标签体的内容转换为大写
         */
        @Override
        public void doTag() throws JspException, IOException {
    ​
            //得到jsp标签体的JspFragment
            JspFragment jspFragment = this.getJspBody();
            StringWriter sw = new StringWriter();
            //将标签体的内容写入到sw流中
            jspFragment.invoke(sw);
            //获取sw缓冲区的内容
            String content = sw.getBuffer().toString();
            content=content.toUpperCase();
            PageContext pageContext=(PageContext) this.getJspContext();
            pageContext.getOut().write(content);
        }
    }
    在WEB-INF目录下添加tld文件对标签处理类的表述
      <tag>
        <name>simple</name>
        <tag-class>simple.tag.SimpleTagOne</tag-class>
        <!-- 标签体允许的内容: scriptless表示标签体内容不允许java脚步代码 -->
        <body-content>scriptless</body-content>
      </tag>
    在JSP页面中导入并使用自定义标签   
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     <%@ taglib uri="/simpletag" prefix="gs" %>
    <!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>
    ​
    <gs:simple>
        <div style="height:10px; background-color:red;">ssgao</div>
    </gs:simple>
    ​
    </body>
    </html>
    

    控制整个JSP页面是否执行

    编写一个类继承SimpleTagSupport,然后在重写doTag方法,在doTag方法里面抛出SkipPageException异常即可,jsp收到整个异常,将忽略标签余下jsp页面的执行
    package simple.tag;
    ​
    import java.io.IOException;
    ​
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.SkipPageException;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    ​
    /**
     * simpleTagSupport实现了SimpleTag接口
     * SimpleTagOne继承了SimpleTagSupport
     * @author ssgao
     *
     */
    public class SimpleTagOne extends SimpleTagSupport{
    ​
        /**
         * 简单标签使用这个方法就可以完成所有业务逻辑
         * javax.servlet.jsp.tagext.SimpleTagSupport#doTag() 
         * 重写doTag方法,控制标签余下的JSP页面不执行
         */
        @Override
        public void doTag() throws JspException, IOException {
    ​
            //抛出一个SkipPageException异常就可以控制标签余下的Jsp不执行
            throw new SkipPageException();
            
        }
    }
    在WEB-INF目录下添加tld文件对标签处理类的表述
      <tag>
        <name>simple</name>
        <tag-class>simple.tag.SimpleTagOne</tag-class>
        <!-- 标签体允许的内容: scriptless表示标签体内容不允许java脚步代码 -->
        <body-content>scriptless</body-content>
      </tag>
    在JSP页面中导入并使用自定义标签   
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
     <%@ taglib uri="/simpletag" prefix="gs" %>
    <!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>
    自定义标签:
    <gs:simple>
        <div style="height:10px; background-color:red;">ssgao</div>
    </gs:simple>
    ssgao
    ssgao
    </body>
    </html>
    

    简单标签开发的一些细节

    标签类编写
        开发标签的时候,不要直接去实现SimpleTag接口,而是继承SimpleTagSupport类,SimpleTagSupport类是SimpleTag接口的一个模拟实现类,通过继承SimpleTagSupport类,就可以
    直接使用SimpleTagSupport类已经实现的那些方法,如果SimpleTagSupport类的方法实现不满足业务需要,那么就可以根据具体的业务情况将相应的方法进行重写。
    
    TLD文件标签体的设置
    我们开发好一个标签后,需要在tld文件中添加对该标签的描述
    <tag>
        <!-- 
        为标签处理器类配一个标签名,在Jsp页面中使用标签时是通过标签名来找到要调用的标签处理器类的
        通过demo1就能找到对应的me.gacl.web.simpletag.SimpleTagDemo1类
        -->
        <name>simple</name>
        <!-- 标签对应的处理器类-->
        <tag-class>simple.tag.SimpleTagOne</tag-class>
        
        <!--    
            tld文件中有四种标签体类型 :empty  JSP  scriptless  tagdepentend  
            在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
            在传统标签中标签体body-content的值只允许是empty和JSP
            如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
            例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
            <gacl:sql>SELECT * FROM USER</gacl:sql>
            在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可 
        -->
        <body-content>scriptless</body-content>
    开发好一个标签后,在tld文件中使用<tag>来描述一个标签,描述的内容包括标签名(name),标签处理器类(tag-class),标签体的内容(bodycontent)
    tld文件中有4种标签体<body-content>类型:empty,jsp.scriptless.tagdependent
    简单的标签的中body-content,不可以设置为JSP,否则会出现异常
    The TLD for the class me.gacl.web.simpletag.SimpleTagDemo1 specifies an invalid body-content (JSP) for a SimpleTag
    body-content的值如果设置为empty,那么就表示该标签没有标签体,如果是设置成scriptless,那么该标签是有标签体,但是标签体的内容不可以是<%java代码%>
    <gs:tag>
       <%
          //嵌套在标签体中的java代码
          int i=0;
        %>
    </gs:tag>
    ​
    运行出错:
    Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here
    ​
    原因:
    JSP标签技术的目的就是为了移除在jsp页面中编写的java代码的,如果在JSP标签中运行出现java代码,那么就违背了jsp标签设计时的初衷了。
    

    传统标签的标签体

         在传统标签的标签体中body-content的值允许是empty,jsp,scriptless,tagdependent,body-content的值如果是设置成JSP,那么表示该标签是有标签体的。并且标签体的内容可以是任意的
    包括java代码,如果是设置成scriptless,那么表示该标签是有标签体,但是标签体的内容不能是java代码。
         如果传统标签和简单标签的标签体body-content的值设置成tagdependent,那么就表示标签体里面的内容是给标签处理器类使用的,tagdependdent用得比较少,了解即可。
    

    TLD文件中标签库的URI设置细节

     一般标签库中的uri不要设置成相同,否则在JSP页面通过uri引用标签库时,就不知道引用哪一个标签库了。
    如果两个标签库的uri刚好一致,解决方法,换一种引用方式:
       <%@ taglib uri="要引用的标签库的TLD文件目录" prefix="gs"%> 
    taglib指令的uri属性指定为标签库的tld文件目录,这样就区分开了。
    引用simple.tld标签库 <%@ taglib uri="/WEB-INF/simple.tld" prefix="gs"%>
    
  • 相关阅读:
    SQL的Demo 由Access改为SQLite
    Delphi10.3ComboBoxEx下拉左边带图标
    uniGUI学习之IconCombobox(53)
    MySQL的图形GUI界面Navicat操作(03)
    delphi10.3安装使用mySQL(02)从SQLite 转移至Mysql
    [转] Java虚拟机原理图解 系列
    [转]ASM插入代码 visitFieldInsn
    [转]大话+图说:Java字节码指令——只为让你懂
    [转]smali语言之locals和registers的区别
    [转]Smali浅析及dex,java互转
  • 原文地址:https://www.cnblogs.com/ssgao/p/8867343.html
Copyright © 2020-2023  润新知