• Java Web 自定义标签


    1.   自定义标签

    由于在JSP页面中直接嵌入Java代码会导致页面开起来非常混乱,不方便和美工等配合工作,为此,JSP提供了自定义标签技术,可以代替直接嵌入Java代码的方式提供动态逻辑,但自定义标签本质上仍然是Java代码

     

     

    1.1. JSTL

    JSTL(JavaServer Pages Standard Tag Library),JSP标准标签库,是一组JSP自定义标签。这些标签原本由第三方开发实现,由于效果质量非常好,sun公司就把这些标签作为标准标签打包成库并加以推广

     

    现在先学习JSTL中主要自定义标签的用法,后面再学习如何定义自己的自定义标签

     

    JSTL按照标签功能分为多个库,主要有:

    标签库

    uri

    建议前缀

    核心标签库

    http://java.sun.com/jsp/jstl/core

    c

    格式化标签库

    http://java.sun.com/jsp/jstl/fmt

    fmt

    函数库

    http://java.sun.com/jsp/jstl/functions

    fn

     

    1.1.1. 核心标签库

    主要包含<c:out>、<c:if>、<c:forEach>标签,要想在JSP页面中使用这些标签,需要使用<%@ taglib >指令引入核心标签库的配置文件(tld文件在对应jar包的META-INF下面)

     

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

     

    指定taglib时需要引入带jsp的uri,这套是新版本(旧版本有时候不好用)

     

    <c:out>

    先把EL表达式计算结果中的特殊字符比如<、& 转换为对应的实体字符,再输出到HTML格式的响应中

     

    JSP页面中

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

     

    <c:out value="${ '<hello>' }" ></c:out>

     

     

    对应JSP生成的Servlet中主要的java代码

    OutTag outTag = tagHandlerPool.get(OutTag.class);

    outTag.setValue(PageContextImpl.proprietaryEvaluate("${ '<hello>' }", Object.class, pageContext, null));

    outTag.doStartTag();

     

    每个自定义标签都对应一个标签类,比如<c:out>对应OutTag,在JSP页面中每使用一次标签,就会执行一次对应标签对象的doStartTag()方法

     

    和EL一样,自定义标签也是在服务器端执行的,客户端也看不到自定义标签,普通HTML注释对自定义标签也是无效的...

     

    浏览器源代码

    &lt;hello&gt;

     

    <c:if>

    相当于Java中的if语句,当EL表达式的值为true时,就会执行其标签体内容,也就是说会把标签体内容加入到HTML格式的响应中。如果为false,就会跳过标签体内容

     

    <c:if test="${ param.age<18 }">

        禁

    </c:if>

     

     

    <c:forEach>

    可以实现普通for循环和增强for循环两种效果

     

    普通for循环效果

    <c:forEach var="i" begin="0" step="1" end="5">

        <c:out value="${ i }"></c:out> <br/>

    </c:forEach>

     

    var指定循环变量,每次循环开始时,内部都会调用pageContext.setAttribute("i", value),所以循环时可以使用EL表达式取出i当前的值。整个循环结束后,内部会调用pageContext.removeAttribute("i") 清理数据

     

    begin指定循环变量的开始值

     

    step指定循环变量的自增量,也称为步长,默认为1

     

    end指定循环变量的结束值,其实循环条件是i <= end

     

    需要注意以上属性都不支持EL表达式

     

    增强for循环效果用来变量集合、数组

    <c:forEach items="${ requestScope.userList }" var="user">

        <c:out value="${ user.name }"></c:out> <br/>

    </c:forEach>

     

    items指定待遍历的集合或者数组,必须使用EL表达式

     

    1.1.2. 格式化标签库

    提供了<fmt:formatDate>标签用来在JSP页面中把Date对象转换为指定格式的字符串,并输出到HTML格式的响应中

     

    <fmt:formatDate value="${ requestScope.user.birthday }" pattern="yyyy-MM-dd"/>

     

     

     

    1.1.3. 函数库

    函数库中提供了很多可以在EL表达式中使用的函数,其实就是一些静态方法,绝大部分都是操作字符串的,比如fn:length、fn:contains、fn:toLowerCase、fn:toUpperCase、fn:trim、fn:split、fn:join、fn:indexOf、fn:replace、fn:startsWith、fn:endWith、fn:substring

     

    ${ fn:length('hello') }

    ${ fn:contains('hello','el') }

     

     

     

    1.2. 定义自己的自定义标签

    定义并使用自己的标签分为三个步骤:

    1 编写自定义标签类

    2 在.tld文件中标签类

    3 在JSP页面中引入tld文件后便可使用自定义标签

     

    下面以模仿<c:if test=””>为例说明

     

    1 MyIfTag.java

    public class MyIfTag extends SimpleTagSupport {

     

        private Boolean test; //对应标签的test属性

     

        @Override

        public void doTag() throws JspException, IOException {

            if (test != null && test) {

                Writer writer = getJspContext().getOut();

                JspFragment tagBody = getJspBody();

                tagBody.invoke(writer);

            }

        }

        public Boolean getTest() {

            return test;

        }

        public void setTest(Boolean test) {

            this.test = test;

        }

    }

     

    标签中需要用到到属性,需要对应标签类中的字段,并为字段提交get/set方法

     

    如果标签中有default属性,由于default在Java中是关键字,可以使用_default变量名,并提供setDefault()方法给_default赋值

     

    JspFragment表示标签体内容,标签体内容可能为空,也可能包含其他标签,也可能嵌入Java代码,其invoke(writer)方法会执行标签体内容,并使用指定writer把执行结果输出到响应中

     

    这里并没有出现前面说的doStartTag()方法,原因是doStartTag()属于早期标签类实现方式,有些复杂。这里使用的是简易的实现方式,即继承SimpleTagSupport

     

     

    2 mytag.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">

       

        <tlib-version>1</tlib-version>   <!-- 标签库内部版本号 -->

        <short-name>my</short-name>   <!-- 建议前缀 -->

        <uri>/my-tag</uri>   <!-- 标签库uri -->

       

        <tag>   <!-- 用来定义标签 -->

            <name>if</name>   <!-- 标签名称 -->  

            <tag-class>com.rupeng.web.tag.MyIfTag</tag-class>   <!-- 标签类 -->

            <body-content>scriptless</body-content>   <!-- 表示标签体中不可嵌入Java代码 -->

            <attribute>   <!-- 用来定义标签属性 -->

                <name>test</name>   <!-- 属性名称 -->

                <required>true</required>   <!-- 属性是否必须 -->

                <rtexprvalue>true</rtexprvalue>   <!-- 属性是否支持EL表达式 -->

            </attribute>

        </tag>

    </taglib>

     

    <body-content>用来指定标签体内容类型,取值如下:

    empty

    标签体为空

    scriptless

    标签体中不可嵌入Java代码,其他无限制

    JSP

    标签体内容不做限制(当前JSP版本已废弃此选项)

     

     

    3 JSP页面中

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

    <%@ taglib uri="/my-tag" prefix="my" %>

    <!DOCTYPE html>

    <html>

        <head>

            <meta charset="UTF-8">

            <title>自定义标签</title>

        </head>

        <body>

            <my:if test="${ param.age<18 }">禁</my:if>

        </body>

    </html>

     

  • 相关阅读:
    MYSQL批量插入数据库实现语句性能分析【转】 批量插入!程序里面对于数据库插入的功能尽量用【异步处理+批量插入+(事务)】
    移动端如何解决页面返回上次浏览位置问题
    php对接java接口
    php后端遇到的问题
    jquery 判断字符串长度
    phpExcel常用方法详解
    html 手机端适配不同手机高度 ,把内容居中显示
    html 手机端 生成海报
    没错,老师就是个勤奋负责有良心的职业,不,的人
    睡眠是自然的第二道菜
  • 原文地址:https://www.cnblogs.com/renjing/p/java-taglib.html
Copyright © 2020-2023  润新知