• web概述19


    自定义标签

    jsp中提供了自定义标签技术,用于在jsp页面中提供简单的业务逻辑处理功能,可以避免在jsp页面中直接编写java代码造成的jsp页面难以维护和分工不清晰的问题

    概述自定义标签

    自定义标签是用户自定义的java页面元素,实质上是运行一个或者两个接口的JavaBean

    • 可以非常紧密的和JSP表示逻辑联系在一起,又具有和普通JavaBean相同的业务逻辑处理能力
    • 当一个jsp页面转换为servlet时,中间的用户自定义标签会转换为操作一个叫做标签处理器的对象
    • 使用自定义标签可以操作默认对象、处理表单数据、访问数据库以及其它的企业级服务

    hello Tag

    1、创建标签处理器类:实际上通过标签调用的具体处理程序

    //直接使用Tag接口编码繁琐,所以一般使用Sun提供的实现Tag接口的类,达到间接使用Tag接口的目的
    //需求:接收2个整型参数,用于计算累加和
    /*
    <标签起始 属性=值>标签体
     */
    public class TestTag extends TagSupport {
        //标签属性值
        private int begin,end;
    
        // 处理器遇到标签起始时回调的方法
        public int doStartTag() throws JspException {
            //可以通过返回不同的常量值告知系统如何处理后续内容--标签体
            return EVAL_BODY_INCLUDE;  //继续处理标签体
            // SKIP_BODY 跳过不处理标签体
        }
        // 遇到标签结束的回调处理方法
        public int doEndTag() throws JspException {
            //具体处理操作
            int res=0;
            for(int k=begin;k<=end;k++){
                res+=k;
            }
            //在页面上输出就和结果
            JspWriter out= pageContext.getOut();
            try {
                out.println(res);
            } catch (Exception e){
                throw new JspException(e);   //交由jsp页面进行异常处理
            }
            //逻辑处理结束后通过返回值控制如何处理后续标签
            return SKIP_BODY;
        }
    
        @Override
        //释放资源
        public void release() {
            super.release();
        }
    
        public int getBegin() {
            return begin;
        }
    
        public void setBegin(int begin) {
            this.begin = begin;
        }
    
        public int getEnd() {
            return end;
        }
    
        public void setEnd(int end) {
            this.end = end;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    2、创建标签描述文件,用于针对标签名称和对应的处理类进行声明定义
    标签库描述文件应该位于/WEB-INF/文件夹下,后缀必须为tld

    
    
    <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">
        
        <tlib-version>1.0tlib-version>
       
        <short-name>yanshort-name>
        
        <uri>/WEB-INF/yan.tlduri>
        
        <tag>
            
            <name>helloname>
            
            <tag-class>com.yan.tag.TestTagtag-class>
            
            <body-content>emptybody-content>
            
            <attribute>
                
                <name>beginname>
                
                <required>truerequired>
            attribute>
            <attribute>
                <name>endname>
                <required>truerequired>
            attribute>
        tag>
    taglib>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3、在页面中使用自定义标签库

    
    <%@ taglib prefix="yan" uri="/WEB-INF/yan.tld" %>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    标签库说明文件

    标签库描述文件简称tld文件,实际上采用的是xml文件格式,用于定义用户的标签库

    tld文中的元素主要可以分为3大类:标签库元素、标签元素和标签属性元素

    标签库元素

    用来设置标签库的相关信息

    • 用来设置标签库默认的前缀名
    • 用于设置标签库的唯一访问标识符,可以通过这个标识符唯一的指定特定的标签库
    标签元素

    用于定义一个标签

    • 用于设定对应的标签名称
    • 用于设定对应的标签处理类。对应的处理类要求实现对应的标签接口
    • 用于设定标签的主体内容。可以使用的属性值有三种:empty表示标签中没有标签体;JSP表示标签体可以加入jsp程序代码;tagdependent表示标签体的内容由标签自身进行处理
    标签属性

    用于设置标签的属性,例如允许使用什么属性

    • 用于设置属性名称
    • 用于设置属性是否为必须的,默认值为false
    • 用于设置属性值是否允许使用表达式,默认false

    总结

    使用自定义标签的目的在于不希望在jsp页面中出现java逻辑代码

    开发流程

    • 定义一个类实现Tag接口或者SimpleTag 接口
      • 有标签体有属性继承BodyTagSupport类
      • 没有标签体继承TagSupport类
    • 在项目的WEB-INF文件夹中添加tld标签库描述文件

    执行过程

    1、当jsp引擎遇到自定义标签时,首先创建标签处理类的实例对象

    2、调用setPageContext方法,将当前页面的PageContext对象传递给标签处理器类对象。有了PageContext则当前标签处理器对象则可以于jsp页面进行通信

    3、setPageContext执行完毕后,则会调用setParent方法将当前标签的父标签对象传递给标签处理器对象。如果当前标签没有父标签,则传入null

    4、当web容器执行到自定义标签的开始标记时,则自动调用doStartTag方法

    5、当web容器指定到自定义标签的结束标记时,则自动调用 doEndTag方法

    6、当web容器指定完自定义标签后,标签处理器对象会驻留在内存中,直到停止web应用时,web容器才会调用release方法执行资源回收

    JSTL

    Sun为了规范自定义标签的使用,因为了标准标签库 JSTL,在JSTL中提供了一系列jsp标签,可以应用于jsp的应用开发过程。

    JSTL标签库总供有5大类,核心标签c、国际化标签fmt,xml标签x,函数标签库fn。其中使用最多的是c标签库

    核心标签库中总共有13个标签,例如out用于页面输出、set用于定义变量、remove用于移除指定对象,if用于条件判断等

    在使用jstl标签库之前需要导入相应的jar包:jstl.jar和standard.jar

    Hello JSTL

    1、在maven的pom.xml中添加依赖

    <dependency>
    	<groupId>javax.servletgroupId>
        <artifactId>jstlartifactId>
        <version>1.2version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2、在页面中使用JSTL的核心标签库

    1、在jsp页面中引入标签库。相关的标签库描述文件可以在jstl.jar的META-INF目录下查找到
    c
    http://java.sun.com/jsp/jstl/core
    
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
    2、在可以中可以通过[prefix:标签名]的方式使用标签
    
            
                
    ${k}*${i}=${i*k}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    EL表达式

    EL表达式的支持在jsp2+已经纳入到jsp规范中,不需要JSTL的支持。主要用于在jsp页面中实现数据输出显示

    • 在静态部分中可以使用${表达式}的方式来获取并输出表达式的值

      <%
          String ss="abc";
          request.setAttribute("ss",ss);
      %>
      ${ss}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 在获取时是在4大范围中查找对应的数据,相当于执行pageConext.findAttribute("key"),如果小范围中没有查找到,则升级到大范围中继续查找,如果找到了则直接输出显示。如果在所有的范围中都没有查找到,不会显示null,而是显示为空串
      • el表达式在输出null时,输出的时空串,但是 jsp 脚本中是输出null
    • 在指定范围中可以数据数据可以使用xxxScope的方式进行访问。例如pageScope、requestScope、sessionScope和applicationScope

      <%
          String ss="abc";
          session.setAttribute("ss",new Date());
          request.setAttribute("ss",ss);
      %>
      ${sessionScope.ss}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 获取类对象中的属性【 对 象 名 . 属 性 名 】 和 【 {对象名.属性名}】和【 .{对象名[‘属性名’]}】,但是需要注意的是实际上调用getXxx方法

      <%
          pageContext.setAttribute("now",new Date());
      %>
      ${now.year+1900}年${now.month+1}月${now.date}日
      
      • 1
      • 2
      • 3
      • 4

      注意:当访问 null对象时,EL不会抛出空指针异常,仅仅就是不输出任何内容

    • 使用EL直接访问集合

      • EL访问数组${数值名称[索引]}。如果越界也不会抛出异常
      • EL访问List集合${List集合名称[索引值]}。如果越界也不会抛出异常,但是无法访问Set集合
      • EL访问Map对象${map['key']}或者${map.key}
    • EL表达式中可以进行响应的计算操作,但是不支持字符串相加

    运算符

    算术运算符+、-、*、/ div、% mod,不支持++、--,除法获取的结果值为浮点型

    关系运算符> gt、< lt 、>= ge、<= le、== eq、!= ne

    逻辑运算符非! not、与&& and、或|| or

    取值运算符方括号[]或者点.

    三目运算符表达式1?表达式2:表达式3

    empty运算符,判断变量为空:1、没有定义的变量;2、值为null的变量、3、值为""的空字符串。4、没有元素的数组或者集合

    内置对象

    pageContext页面上下文,可以通过pageContext获取 jsp 页面中的其它默认对象,例如request、response、session等

    ​ 4大范围pagepageContext.addAttribute()

    param获取请求中的指定请求参数值,底层调用实际上是通过request.getParameter获取提交数据

    paramValues获取请求中指定名称所对应的所有值,底层调用实际上是request.getParameterValues()获取

    initPram获取当前应用的初始化参数,底层调用servletContext.getInitParameter

    header用于获取请求头信息

    headerValues获取请求头中指定属性的所有取值

    cookie使用客户端跟踪用户的方法

    总结

    使用EL表达式可以替换jsp中的输出表达式脚本,但是针对代码脚本并没有很好的解决方案

    1、 不使用EL实现报错页面的输入框的数据回填

    <%!
    public String getParamValues(HttpServletRequest request,String key){
        String ss=request.getParameter("username");
        if(ss!=null && ss.trim().length()>0)  
            return ss;
        return "";
    }    
    %>
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、引入EL后可以直接使用

    
    
    • 1

    JSTL引入

    引入JSTL就是为了取代传统方法中在JSP页面中添加java程序的做法,以提高程序的可读性、维护性和便捷性,能够使jsp页面变得更加简洁

    c核心标签库

    tld文件jstl.jar中的META-INF目录下c.tld

    1、用于输出数据,可以是字符串或者表达式,相当于脚本中的<% out.println()%>或者<%= %>

    • value指定需要输出的内容,一般使用EL表达式
    • default用于指定如果value值为null时输出的数据
    • escapeXml指定是否需要进行实体字符转换,默认值为true
    <%
    request.setAttribute("username","张三");
    %>
    
    李四
    
    //在页面上可以直接看到输出内容张三,实际上在html代码可以看到特殊符号已经转换为实体字符,例如空格对应的内容为 ,>对应的内容>
    
    李四  由于针对username对应的字符串内容按照原样输出,并不进行实体字符转换,所以在浏览器看到的是一个红色的 张三  这样的显示
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、用于把一个对象存储到指定的域分为内或者将一个对象存储到Map或者javaBean中

    • value用于指定属性值
    • var用于指定要设置的域属性的名称
    • scope用于指定所在的域
    • property用于指定为对象设置的属性名称
    • target用于指定要设置属性的对象,必须是java bean对象或者map对象

    注意:var和property不能同时存在、target和scope不能同时存在

    针对JavaBean的操作

    构建一个javabean对象
    
    
    向javabean中的属性进行赋值----setXxx方法
    
    输出   ${student} 或者使用
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    针对Map的操作

    <%
    Map map=new HashMap<>();
    request.setAttribute("map",map);   // 需要注意:在标签中使用或者通过EL访问的变量必须在4大范围中
    %>
    
    张三
    ${map}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    将某个对象存储到指定的scope中

    张三和李四
    输出${sessionScope.username},相当于session.getAttribute("username")     
    
    • 1
    • 2

    3、用于从指定的jsp范围中移除指定的变量,属性有2个var和scope。相当于调用removeAttribute操作

      没有设置scope则默认值为page
    小张
    
    
    
    ${student} 没有对应的输出
    ${empty(student.username) ? "已经被删除":"还是存在"}   判断student.username是否为空
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4、用于捕获抛出的异常

    
    
    
        abcd
    
    出现的异常对象为${eee}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5、用于实现流程控制

    • test是一个条件表达式,用于决定标签体中的内容是否执行,true执行,false不执行
    • var用于指定将条件表达式的计算结果存储到scope指定范围时所采用的名称
    123
    ${yyy mod 2}
    
    ${yyy}是偶数 ${yyy}不是偶数
    • 1
    • 2
    • 3
    • 4
    • 5

    6、组合使用,用于实现开关分支语句,相当于switch/case语句

    其中没有表达式,只是表示开关分支结构的开始;中test属性是一个条件判断,条件成立则执行标签体;是所有都不成立时执行的内容

    <% String name="李四";
    pageContext.setAttribute("name",name);%>
    
        
            欢迎李四
        
        
            欢迎王五
        
        
            欢迎其它人
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    特殊情况下可以使用结构实现if/else效果

    <% request.setAttribute("sex",true); %>
    
        
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    7、用于实现循环迭代操作

    • var设定临时变量名用于存储从集合中获取的元素
    • items用于指定需要遍历的集合
    • begin遍历的起始值、end遍历的终止值[允许相等]、step遍历时采用的不常置
    • varStatus用于设定变量名,该变量用于存放集合中元素的信息,例如索引号、序号等
      • index:int 当前循环的索引值
      • count:int 循环的次数
      • first:boolean 是否为第一个元素
      • last:boolean 是否为最后一个元素
    <%
    List list=new ArrayList<>();
    list.add("aaa");list.add("bbb");
    list.add("ccc");list.add("ddd");
    list.add("eee");list.add("fff");
    request.setAttribute("list",list);
    %>
    
        ${tt}

    ${tt}

    ${tt}---${ss.index}---${ss.count}---${ss.first}---${ss.last}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    8、用于将字符串以指定分割符进行分割,并迭代访问分割后的每一端内容

    items参数只能是字符串,delims用于指定分割符

    
    	${ss}
    • 1
    • 2
    • 3

    9、用于将其它静态或者动态文件包含到当前jsp页面中

    • url要包含的资源路径
    • context用于访问其它web应用时指定对应的根目录,如果访问的是同一个web应用中的其它资源以/开头
    • var保存导入的文件内容,以String的方式存储
    
        
        ${ss}
    
    
    
        ${err}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用正确的

    的区别

    • 只能包含同一个web应用中的文件,而可以包含其它web应用中的文件,甚至是网络上的资源

    10、主要用于进行URL相关操作时添加额外参数的,可以嵌套在或者标签内,用于给这些标签的url地址上添加参数。这个标签添加参数时会自动对参数值进行URL编码

    11、用于在jsp页面中构建一个URL地址,主要目的实现URL重写

    
    	    test.jsp?username=zhangsan
    
    
    地址已经重写了
    
    • 1
    • 2
    • 3
    • 4
    • 5

    12、用于实现请求的重定向操作,可以配合在url地址中指定参数

    
    	
        
    
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    LeetCode 每日一题 2023/9/25-2023/10/1
    数据资产、数字资产、数据资源及数据资产入表
    lab3_系统调用(下)
    Cadence OrCAD Capture管脚Passive和Power属性功能详细介绍图文教程
    Linux之(10)shell基础语法(2)
    基于libmpv内核设计开发的视频播放器-高级版(四)
    (数据科学学习手札136)Python中基于joblib实现极简并行计算加速
    9 个让你的 Python 代码更快的小技巧
    Map和Set
    深度学习基础--神经网络(1)激活函数
  • 原文地址:https://blog.csdn.net/weixin_44251806/article/details/128047297