Java Web 从入门到退坑 第九章 EL表达式&JSTL标签库


Java Web 从入门到退坑 —— 第九章 EL表达式&JSTL标签库


By -gregPerlinLi-


1. EL 表达式

1.1. 什么是 EL 表达式,EL 表达式的作用

​ EL 表达式的全称是:Expression Language 是表达式语言。

EL 表达式的作用:

​ EL 表达式主要是用于替代 jsp 页面中的表达式脚本,在 jsp 页面中进行数据的输出,因为 EL 表达式在输出数据的时候要比 jsp 的表达式脚本要简洁很多

EL 表达式输出的格式是:${ Expression }

​ EL 表达式在输出 null 值的时候,输出的是空串,jsp 表达式脚本输出 null 值的时候,输出的是 null 字符串。

示例代码:

<body>
    <%
        request.setAttribute("key", "value");
    %>
    Expression script output: <%=request.getAttribute("key") == null ? "" : request.getAttribute("key") %> <br/>
    EL Expression output: $&#123; key &#125; <br/>
</body>

1.2. EL 表达式搜索域数据的顺序

​ EL 表达式主要是在 jsp 页面中输出数据。

​ 主要是输出域对象中的数据

​ 当四个域中都有相同的 key 数据的时候,EL 表达式会按照四个域的从小到大的顺序进行搜索,找到后进行输出:

pageContext >> request >> session >> application

示例代码:

<body>
    <%
        // The same key data is saved in all four domains
        pageContext.setAttribute("key", "pageContext");
        request.setAttribute("key", "request");
        session.setAttribute("key", "session");
        application.setAttribute("key", "application");
    %>
    $&#123; key &#125;
</body>

1.3. EL 表达式输出 Bean 的普通属性,数组属性。List 集合属性,map 集合属性

示例代码:

Person.java

public class Person &#123;
    // 1. Output the general properties, array properties, List set and Map set properties in the person class
    private String name;
    private String[] phones;
    private List<String> cities;
    private Map<String, Object> map;
    private final int age = 18;
    public Person() &#123;

    &#125;
    public Person(String name, String[] phones, List<String> cities, Map<String, Object> map) &#123;
        this.name = name;
        this.phones = phones;
        this.cities = cities;
        this.map = map;
    &#125;
    public String getName() &#123;
        return name;
    &#125;
    public void setName(String name) &#123;
        this.name = name;
    &#125;
    public String[] getPhones() &#123;
        return phones;
    &#125;
    public void setPhones(String[] phones) &#123;
        this.phones = phones;
    &#125;
    public List<String> getCities() &#123;
        return cities;
    &#125;
    public void setCities(List<String> cities) &#123;
        this.cities = cities;
    &#125;
    public Map<String, Object> getMap() &#123;
        return map;
    &#125;
    public void setMap(Map<String, Object> map) &#123;
        this.map = map;
    &#125;
    public int getAge() &#123;
        return age;
    &#125;
    @Override
    public String toString() &#123;
        return "Person&#123;" +
                "name='" + name + '\'' +
                ", phones=" + Arrays.toString(phones) +
                ", cities=" + cities +
                ", map=" + map +
                ", age=" + age +
                '&#125;';
    &#125;
&#125;

c.jsp

<body>
    <%
        Person person = new Person();
        person.setName("XingMing");
        person.setPhones(new String[]&#123;"13624887499", "18688886666", "18699998888"&#125;);
        List<String> cities = new ArrayList<String>();
        cities.add("Beijing");
        cities.add("Shanghai");
        cities.add("Guangzhou");
        cities.add("Shenzhen");
        person.setCities(cities);
        Map<String, Object> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");
        map.put("key4", "value4");
        map.put("key5", "value5");
        person.setMap(map);
        request.setAttribute("person", person);
    %>
    Output Person: $&#123; person &#125; <br/>
    Output Name: $&#123; person.name &#125; <br/>
    Output Phones: $&#123; person.phones[0] &#125;, $&#123; person.phones[1] &#125;, $&#123; person.phones[2] &#125; <br/>
    Output Cities: $&#123; person.cities &#125; <br/>
    Output City 1: $&#123; person.cities[0] &#125; <br/>
    Output Maps: $&#123; person.map &#125; <br/>
    Output the value of key in Map: $&#123; person.map.key1 &#125; <br/>
    Output Age: $&#123; person.age &#125; <br/>
</body>

注意⚠️: EL 表达式中的输出属性值其实是利用了 BeanGet 方法来实现的。

1.4. EL 表达式 —— 运算

语法:${ OperationalExpression }

​ EL 表达式支持如下运算符:

1.4.1. 关系运算

关系运算符 说明 范例 结果
==eq 等于 ${ 5 == 5 }${ 5 eq 5 } true
!=ne 不等于 ${ 5 != 5 }${ 5 ne 5 } false
<lt 小于 ${ 3 < 5 }${ 3 lt 5 } true
>gt 大于 ${ 2 == 10 }${ 2 gt 10 } false
<=le 小于等于 ${ 5 == 12 }${ 5 le 12 } true
>=ge 大于等于 ${ 3 == 5 }${ 3 ge 5 } false

1.4.2. 逻辑运算

逻辑运算符 说明 范例 结果
&&and 与运算 ${ 12 == 12 && 12 < 11 }${ 12 eq 12 and 12 lt 11 } false
` or` 或运算
!not 取反运算 ${ !true }${ not true } false

1.4.3. 算术运算

算术运算符 说明 范例 结果
+ 加法 ${ 12 + 18 } 30
- 减法 ${ 18 - 8 } 10
* 乘法 ${ 12 * 12 } 144
/div 除法 ${ 144 / 12 }${ 144 div 12 } 12
%mod 取模 ${ 144 % 10 }${ 144 mod 10 } 4

1.4.4. empty 运算

empty 运算可以判断一个数据是否为空,如果为空,则输出 true,不为空输出false

以下几种情况为空:

​ 1. 值为 null 的时候为空

​ 2. 值为空串的时候为空

​ 3. 值是 Object 类型数组,长度为零的时候为空

​ 4. List 集合元素个数为零的时候为空

​ 5. Map 集合元素个数为零的时候为空

1.4.5. 三元运算

${ Expression1 ? Expression2 : Expression3 }

​ 如果表达式1的值为真,返回表达式2的值,如果表达式1的值为假,返回表达式3的值

示例:

${ 12 != 12 ? "Equal" : "Unequal" }

1.4.6. . 点运算和 [] 中括号运算

. 点运算可以输出 Bean 对象中某个属性的值。

[] 中括号运算可以输出有序集合中某个元素的值。

​ 中括号运算还可以输出 Map 集合中 key 里含有特殊字符的 key 的值。

示例:

${ map.["a.a.a"] }
${ map.['b+b+b'] }

1.4.7. EL 表达式的 11 个隐含对象

​ EL 表达式中 11 个隐含对象,是 EL 表达式自己定义的,可以直接使用。

变量 类型 作用
pageContext pageContextImpl 它可以获取 jsp 中的九大内置对象
pageScope Map<String, Object> 它可以获取 pageContext 域中的数据
requestScope Map<String, Object> 它可以获取 request 域中的数据
sessionScope Map<String, Object> 它可以获取 session 域中的数据
applicationScope Map<String, Object> 它可以获取 application 域中的数据
param Map<String, String> 它可以获取请求参数的值
paramValues Map<String, String[]> 它可以获取请求参数的值(获取多个值的时候使用)
header Map<String, String> 它可以获取请求头的信息
headerValues Map<String, String[]> 它可以获取请求头的信息(它可以获取多个值的情况)
cookie Map<String, Cookie> 它可以获取当前请求的 Cookie 信息
initParm Map<String, String> 它可以获取 web.xml 中配置的 <context-param> 上下文参数

1. 获取四个特定域中的属性

pageScopepageContext

requestScoperequestConotext

sessionScopesessionContext

applicationScopeservletContext

示例代码:

<body>
    <%
        pageContext.setAttribute("key", "pageContext");
        request.setAttribute("key", "request");
        session.setAttribute("key", "session");
        application.setAttribute("key", "application");
    %>
    $&#123; pageScope.key &#125; <br/>
    $&#123; requestScope.key &#125; <br/>
    $&#123; sessionScope.key &#125; <br/>
    $&#123; applicationScope.key &#125; <br/>
</body>

2. pageContext 对象的使用

常用于:

​ I 协议

​ II 服务器 ip

​ III 服务器端口

​ IV 获取工程路径

​ V 获取请求方法

​ VI 获取客户端 ip 地址

​ VII 获取会话饿 id 编号

示例代码:

​ 方法1:

<body>
    1. Agreement: $&#123; pageContext.request.scheme &#125; <br/>
    2. Server IP address: $&#123; pageContext.request.getServerName() &#125; <br/>
    3. Server port: $&#123; pageContext.request.getServerPort() &#125; <br/>
    4. Get project path: $&#123; pageContext.request.getContextPath() &#125; <br/>
    5. Get request method: $&#123; pageContext.request.getMethod() &#125; <br/>
    6. Get client IP address: $&#123; pageContext.request.getRemoteHost() &#125; <br/>
    7. Get session ID number: $&#123; pageContext.session.getId() &#125; <br/>
</body>

​ 方法2:

<body>
      <%
                pageContext.setAttribute("req", request);
              pageContext.setAttribute("ses", session)
      %>
    1. Agreement: $&#123; req.scheme &#125; <br/>
    2. Server IP address: $&#123; req.getServerName() &#125; <br/>
    3. Server port: $&#123; req.getServerPort() &#125; <br/>
    4. Get project path: $&#123; req.getContextPath() &#125; <br/>
    5. Get request method: $&#123; req.getMethod() &#125; <br/>
    6. Get client IP address: $&#123; req.getRemoteHost() &#125; <br/>
    7. Get session ID number: $&#123; ses.getId() &#125; <br/>
</body>

3. EL 表达式其他隐含对象的使用

变量 类型 作用
param Map<String, String> 它可以获取请求参数的值
paramValues Map<String, String[]> 它可以获取请求参数的值(获取多个值的时候使用)

示例代码:

​ 请求地址:

http://localhost:8080/EL_JSTL/otherElObj.jsp?username=gregPerlinLi&password=root&hobby=java&hobby=cpp&hobby=python
<body>
    Username: $&#123; param.username &#125; <br/>
    Password: $&#123; param.password &#125; <br/>
    Hobby: $&#123; paramValues.hobby[0] &#125;, $&#123; paramValues.hobby[1] &#125;, $&#123; paramValues.hobby[2] &#125; <br/>
</body>
变量 类型 作用
header Map<String, String> 它可以获取请求头的信息
headerValues Map<String, String[]> 它可以获取请求头的信息(它可以获取多个值的情况)

示例代码:

<body>
    Header: $&#123; header &#125; <br/>
    User-Agent: $&#123; header["User-Agent"] &#125; <br/>
    Connection: $&#123; header["Connection"] &#125; <br/>
    User-Agent: $&#123; headerValues["User-Agent"][0] &#125; <br/>
</body>
变量 类型 作用
cookie Map<String, Cookie> 它可以获取当前请求的 Cookie 信息

示例代码:

<body>
        Cookie: $&#123; cookie &#125; <br/>
    Cookie name: $&#123; cookie.JSESSIONID.name &#125; <br/>
    Cookie value: $&#123; cookie.JSESSIONID.value &#125; <br/>
</body>
变量 类型 作用
initParm Map<String, String> 它可以获取 web.xml 中配置的 <context-param> 上下文参数

示例代码:

web.xml

<context-param>
    <param-name>username</param-name>
    <param-value>gregPerlinLi</param-value>
</context-param>
<context-param>
    <param-name>url</param-name>
    <param-value>jdbc:mysql://localhost:3306/test</param-value>
</context-param>

otherElObj.jsp

<body>
    Initialize parameter: $&#123; initParam &#125; <br/>
    Initialize username: $&#123; initParam.username &#125; <br/>
    Initialize url: $&#123; initParam.url &#125; <br/>
</body>

2. JSTL 标签库(重点)

​ JSTL 标签库的全称是 JSP Standard Tag Library jsp 标准标签库,是一个不断完善的开放源代码的 jsp 标签库。

​ EL 表达式主要是为了替代 jsp 中的表达式脚本,而 JSTL 则是为了替换 jsp 中的代码脚本,这样使得整个 jsp 页面变得更加简洁。

JSTL 由5个不同的标签库组成

功能范围 URI 前缀
核心标签库(重点) http://java.sum/com/jsp/jst/core c
格式化 http://java.sum/com/jsp/jst/fmt fmt
函数 http://java.sum/com/jsp/jst/functions fn
数据库(不使用) http://java.sum/com/jsp/jst/sql sql
XML(不使用) http://java.sum/com/jsp/jst/xml x

在 jsp 中使用 taglib 指令引入标签库

CORE 标签库

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

XML 标签库

<%@ taglib prefix="x" uri="http://java.sum/com/jsp/jst/xml" %>

FMT 标签库

<%@ taglib prefix="fmt" uri="http://java.sum/com/jsp/jst/fmt" %>

SQL 标签库

<%@ taglib prefix="sql" uri="http://java.sum/com/jsp/jst/sql" %>

FUNCTIONS 标签库

<%@ taglib prefix="fn" uri="http://java.sum/com/jsp/jst/functions" %>

2.1. JSTL 标签库的使用步骤

​ 1. 先导入 JSTL 标签库的 jar

​ 2. 使用 taglib 指令引入标签库

2.2. CORE 核心库的使用

2.2.1. <c:set/> 标签

作用:set 标签可以往域中保存数据

示例代码:

<body>
    <%--
        <c:set/>
        fieldObject.setAtribute(key, value)
        scope: Set which domain to save to 
            page --> pageContext field (default)
            request --> request field
            session --> session field
            application --> application field
        var: Set the key
        value: Set the value
    --%>
    Before: $&#123; requestScope.abc &#125; <br/>
    <C:set scope="request" var="abc" value="abcValue" />
    After: $&#123; requestScope.abc &#125; <br/>
</body>

2.2.2. <c:if/> 标签

作用: 可以用来做 if 判断

示例代码:

<body>
   <%--
        <c:if/>
        test: Conditions of judgment (using EL expression to output)
    --%>
    <c:if test="$&#123; 12 == 12 &#125;">
        <h1>12 == 12</h1>
    </c:if>
    <br/>
    <c:if test="$&#123; 12 != 12 &#125;">
        <h1>12 != 12</h1>
    </c:if>
</body>

2.2.3. <c:choice> <c:when> <c:otherwise> 标签

作用: 多路判断,与 switch...case...default 非常接近

注意⚠️:

​ 1. 标签里不能使用 HTML 注释,要使用 jsp 注释。

​ 2. when 标签的父标签一定要是 choice 标签,想做多路判断的时候一定要先写 choice 标签。

示例代码:

<body>
      <%--
        <c:choice> <c:when> <c:otherwise>
        choice: Start choosing judgment
        when: Every judgment
            test --> The value of the current judgment
        otherwise: The rest situation
        Attention:  1. HTML comments cannot be used in tags. Instead, use JSP annotations.
                    2. The parent of the when tag must be the choice tag, when you want to make multi-channel judgment, you must first write the choice tag.
    --%>
    <%
        request.setAttribute("height", "195");
    %>
    <c:choose>
        <c:when test="$&#123; requestScope.height >= 190 &#125;">
            <h1>You are a giant!</h1>
        </c:when>
        <c:when test="$&#123; requestScope.height >= 180 &#125;">
            <h2>You are quite tall</h2>
        </c:when>
        <c:when test="$&#123; requestScope.height >= 180 &#125;">
            <h3>You are quite tall</h3>
        </c:when>
        <c:when test="$&#123; requestScope.height >= 170 &#125;">
            <h4>it 's not bad</h4>
        </c:when>
        <c:otherwise>
            <h5>The situation that lower than 170</h5><br/>
            <c:choose>
                <c:when test="$&#123; requestScope.height >= 160 &#125;">
                    <h5>Taller than 160</h5>
                </c:when>
                <c:when test="$&#123; requestScope.height >= 150 &#125;">
                    <h5>Taller than 150</h5>
                </c:when>
                <c:when test="$&#123; requestScope.height >= 140 &#125;">
                    <h5>Taller than 140</h5>
                </c:when>
                <c:otherwise>
                    <h5>Lower than 140</h5>
                </c:otherwise>
            </c:choose>
        </c:otherwise>
    </c:choose>
</body>

2.2.4. <c:forEach/> 标签

作用: 遍历输出使用

示例代码:

<body>
    <%--
        1. Traverse from 1 to 100 and output
        begin: Set start index
        end: Set end index
        step: Step value of traversal
        var: Variable of the loop (It is also the data currently being traversed)
        varStatus: The state of the data currently traversed
        for( int i = 1; i <= 10; i++ ) &#123;&#125;
    --%>
    <table>
        <c:forEach begin="1" end="10" var="i">
            <tr>
                <td>The $&#123; i &#125; row</td>
            </tr>
        </c:forEach>
    </table>
    <hr/>
    <%--
        2. Traversing object array
        items: Traversal data source (traversal collection)
        var: Data currently traversed
        for( Object : arr ) &#123;&#125;
    --%>
    <%
        request.setAttribute("array", new String[]&#123;"13622887499", "13112224356", "13766543245"&#125;);
    %>
    <c:forEach items="$&#123; requestScope.array &#125;" var="item">
        $&#123; item &#125; <br/>
    </c:forEach>
    <hr/>
    <%--
        3. Traversing the List collection
    --%>
    <%
        List<Student> studentList = new ArrayList<Student>();
        for (int i = 1; i <= 10; i++) &#123;
            studentList.add(new Student(i, "username" + i, "pass" + i, 18 + i, "phone" + i));
        &#125;
        request.setAttribute("student", studentList);
    %>
    <table>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Password</th>
            <th>Age</th>
            <th>Phone</th>
        </tr>
        <c:forEach items="$&#123; requestScope.student &#125;" var="student">
            <tr>
                <td>$&#123; student.id &#125;</td>
                <td>$&#123; student.username &#125;</td>
                <td>$&#123; student.password &#125;</td>
                <td>$&#123; student.age &#125;</td>
                <td>$&#123; student.phone &#125;</td>
            </tr>
        </c:forEach>
    </table>
    <hr/>
    <%--
        4. Traversing the Map collection
        for( Map.Entry<String, Object> entry : map.entrySet() ) &#123;&#125;
    --%>
    <%
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");
        map.put("key4", "value4");
        map.put("key5", "value5");
        request.setAttribute("map", map);
    %>
    <table>
        <tr>
            <th>Map</th>
            <th>Key</th>
            <th>Value</th>
              <th>Operation</th>
        </tr>
        <c:forEach items="$&#123; requestScope.map &#125;" var="entry">
            <tr>
                <td>$&#123; entry &#125;</td>
                <td>$&#123; entry.key &#125;</td>
                <td>$&#123; entry.value &#125;</td>
                  <td>Delete, Update</td>
            </tr>
        </c:forEach>
    </table>
</body>


文章作者: gregPerlinLi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 gregPerlinLi !
  目录