Java 杂谈善倾的知识体系构建之路

EL & JSTL

2018-09-01  本文已影响0人  善倾

在 JSP 中使用原生 java 代码会造成页面可读性很差,难以维护,所以就想出了使用标签来解决这个问题。标签的思想就是,使用的一种看起来更简洁、用起来方便的符号来替代在 JSP 页面中写 java 代码,使得编写 JSP 页面变的更简单。通过查看源码即可证明,事实如此。

EL 表达式

EL 表达式,全称为 Expression Language 。把它理解成是一个在 JSP 页面中通过 .这个运算符就可以访问 page、request、session、appliaction 四个域对象内部属性的符号就可以了。使用的时候,最好显示指定是从哪个域中获取属性,比如:${requestScope.userName}。如果不指定,它就会从最小的域 page 中查找,找不到就到去 request 然后是 session 最后是 application 。

表达式的运算顺序是从左到右,将运算结果强制以字符串形式输出。以字符串形式输出、以字符串形式输出、以字符串形式输出,重要的事情说三遍。

通常它都是配合 JSTL 标签来一起使用的,可以实现无 java 代码的 JSP 页面,而且支持多级查找。

EL 表达式的运算符分类

虽然取值是 el 最常用的,但有时候也会需要它来进行运算。 EL 表达式的运算符可以分为以下几类

JSTL

JSTL 全称是 JavaServer Pages Standard Tag Libary ,也就是 JSP 标准标签库。它可以分为 5 类,分别是:核心标签库、国际化标签库、JSTL 函数、SQL 标签、XML 标签。

要想要在 JSP 中使用 JSTL 标签库,必须要使用 JSP 的 taglib 指令将指定的标签库导入到 JSP 文件中,类似于 import 的功能!比如使用<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>表示想要使用核心标签库。也就是说必须要指定 url 和 prefix 两个属性,其他标签库如下表:

类别名称 类别英文名称 uri prefix
核心库 core http://java.sun.com/jsp/jstl/core c
国际化库 fmt http://java.sun.com/jsp/jstl/fmt fmt
函数库 functions http://java.sun.com/jsp/jstl/functions fn
sql库 sql http://java.sun.com/jsp/jstl/sql sql
xml库 xml http://java.sun.com/jsp/jstl/xml xml

知道 JSTL 可以分为这 5 个标签库就可以了,目前只要掌握核心库的部分标签即可,sql 库和 xml 库基本不会用它,因为如今的 JSP 只负责显示。想象自定义标签是怎么做的,就能理解 JSTL 标签的核心原理了,下面有讲到。

JSTL 中的核心库

核心库中设计了一些用来替代 Java 代码中的 if else for循环等语句的功能,而且它的功能更强大,用起来更方便。

核心库中的 if 标签

该标签就是对应着 Java 语言中的 if 语句。if 标签有三个属性,分别是:

//使用范例
<c:if test= "${requestScope.userName == `keqi`}" var="isLogin" scope= "sessionScope">
    login success.
</c:if>
//如果要用 else 怎么办呢?
//通过 el 表达式从scope中取值进行else的逻辑处理
//如:${sessionScope.isLogin}

上述代码的含义是,判断 request 对象中 userName 属性是否等于 keqi ,如果等于会执行标签体中的内容,也就是会输出 login seccess. 。这个过程相当于以下 Java 代码:

//el表达式取得数据,然后将判断结果赋值到 test 中
userName = request.getAttribute("userName");
boolean test = userName.equals("keqi");
//将 var 和 test 作为属性名和属性值赋值到 session 对象中
session.setAttribute("isLogin",test);

以后在使用此 if 标签时,如果是仅需要用到 test 属性,另外两个就可以省略,否则三个属性必须写全来。此标签的逻辑无非就是利用 el 表达式进行逻辑判断,将判断结果输出到 test 中,然后把它和 var 组成键值对,放到对应的 scope 对象中去而已。

核心库中的 choose 、when 和 otherwise 标签

这三个标签就相当于是 java 语言中的 switch 、case 和 default 语句,下面以一个 request 中属性名为 fun 的属性为例,进行判断。

<c:choose>
    <c:when test="${requestScope.fun == 'A'}">
        A
    </c:when>
    <c:when test="${requestScope.fun == 'B'}">
        B
    </c:when>
    <c:otherwise>
        C
    </c:otherwise>
</c:choose>

上述标签的就相当于是以下 Java 代码。

switch(fun){
    case: A
        //输出A
        break;
    case: B
        //输出B
        break;
    default: 
        //输出C
        break;
}

从这里可以得出学习启示,在使用 JSP 标签的时候,结合 Java 中对应的语句去理解,去记忆,去思考就简单了。

核心库中的 foreach 标签

foreach 标签顾名思义就是实现循环功能的。它有两种使用方式,且有 6 个属性分别是:

foreach 标签第一种使用方式,和 Java 中的普通 for 循环相同。

 //此标签将循环从1输出到5
<c:foreach var="x" begin="1" end="5" step="1">
     ${x}
</c:foreach>

foreach 标签第二种使用方式,其中 items 属性要放在 var 前面

//循环输出了list集合对象
<c:foreach items="${list} var="x">
    ${x}
</c:foreach>
//循环输出map集合对象,直接使用.key 和.value 进行输出
<c:foreach items="${map}" var="x" >
    ${x.key}:${x.value}
</c:foreach> 

国际化标签库中还有对数字和日期进行格式转换的标签,函数库中还有很多针对字符串的标签,以后用到了再来总结。

自定义标签库

JSTL 还支持定义个性化的标签库,总共分为三个步骤:

定义一个类继承 SimpleTagSupport 类,重写它的doTag()setJspContext()方法。JSP 中使用标签时,调用的就是这个 doTag() 方法。

public class MyFirstTag extends SimpleTagSupport{
    JspContext jspContext;
    public void doTag() throws IOException, JspException {
        jspContext.getOut().print("This is my first tag.");
    }
    public void setJspContext(JspContext jspContext) {
        this.jspContext = jspContext;
    }
}

编写一个标签库文件 .tld ,并注册此标签

<?xml version="1.0" encoding="UTF-8"?>
<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 web-jsptaglibrary_2_1.xsd"
    version="2.1">
    <tlib-version>1.0</tlib-version>
    <short-name>My First Taglib Example</short-name>
    <!--JSP页面中是通过此url找到该文件的-->
    <uri>http://www.keqi.tag</uri>
    <tag>
        <name>firstTag</name>
        <tag-class>app06a.customtag.MyFirstTag</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>

在 JSP 页面中使用自定义的 firstTag 标签

<%@ taglib uri="http://www.keqi.tag" prefix="easy"%>
<html>
<head>
    <title>Testing my first tag</title>
</head>
<body>
Hello!!!!
<br/>
<easy:firstTag></easy:firstTag>
</body>
</html>

从这里可以发现每个标签库对应一个 .tld 文件,每个标签对应该文件中的一个tag元素。标签背后都有一个 Java 类,每次使用标签都是调用这个类的 doTag() 方法。

总结就是,每次使用标签都是这样的流程:通过 url 找到标签库的 .tld 文件,通过标签名找到对应的类,然后调用该类的 doTag() 方法执行该标签完成的功能而已。理解了这一点,就不会觉得标签很虚了,不知道是设么东西了。

补充:这里的 .tld 文件其实就是一个 xml 文件,但这时候会有一个疑问。明明是 xml 文件,为什么后缀又是 .tld 呢?其实对于计算机来说,根本就没有什么文件格式的区分,都是二进制文件。后缀名只是用来给人看的,表示这是一个什么类型的文件,具体的应用软件会区分文件格式,是因为它也是使用者。一句话,文件的后缀名其实一点也不特殊,以后不要被那种看起来就感觉很牛逼的文件后缀名给吓到了,其实他什么都不是。

上一篇下一篇

猜你喜欢

热点阅读