JavaWeb学习笔记(十八)--EL表达式

1. EL表达式简介

EL 全名为Expression Language。EL主要作用:

  1. 获取数据:EL表达式主要用于替换JSP页面中的**脚本表达式,以从各种类型的 web域中检索Java对象**,获取数据。(某个web域中的对象,访问Jabvbean的属性,List集合,Map集合,数组)
  2. 执行运算:利用EL表达式可以在JSP页面中执行一些基本的关系运算,逻辑运算和算术运。
  3. 获取web开发的常用对象:EL表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松的获取对web常用对象的引用,从而获得这些对象中的数据。
  4. 调用Java方法:EL表达式允许用户开发自定义的EL函数,以在JSP页面中通过EL表达式调用Java类的方法。

补充说明:EL表达式中$不能嵌套,只需要在最{}外面使用一个$即可。

1.1 获取数据

使用EL表达式获取数据语法: ${标识符}

EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找对应的对象,找到返回响应的对象,找不到则返回“”(注意是空字符串,不是null)

EL表达式也可以很轻松的获取JavaBean的属性,获取数组、Colleciton、Map的数据。

结合JSTL的foreach标签,使用EL表达式可以很轻松的迭代各种类型的数组或集合。

如何使用JSTL核心标签:

首先需要导入JSTL的jar包,访问https://tomcat.apache.org/download-taglibs.cgi 下载如下3个Jar包,导入到JaveWeb工程中:

Impl:taglibs-standard-impl-1.2.5.jar (pgp, sha512)

Spec:taglibs-standard-spec-1.2.5.jar (pgp, sha512)

EL:taglibs-standard-jstlel-1.2.5.jar (pgp, sha512)

在JSP中引用核心标签库:

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

uri的地址可以在taglibs-standard-impl-1.2.5.jar中的c.tld的uri标签中获取,所有的核心标签也在此文件中标注说明。

举例:

package javabean;

public class Person {
    private String name;
    private int personAge;
    private Address address;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return personAge;
    }

    public void setAge(int personAge) {
        this.personAge = personAge;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}
package javabean;

public class Address {
    private String city;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}
<%@ page import="javabean.Person" %>
<%@ page import="javabean.Address" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>EL表达式获取数据</title>
</head>
<body>
<b>获取字符串:</b><br>
<%
    request.setAttribute("data", "requestDate");
%>
data=${data}<br>
<hr>

<%
    Person p = new Person();
    p.setName("zhangsan");
    p.setAge(18);
    Address address = new Address();
    address.setCity("beijing");
    p.setAddress(address);
    request.setAttribute("person", p);
%>
<b>获取JavaBean的属性:</b><br>
name = ${person.name}<br>
age = ${person.age}<br> <!--可以看到这个是根据getAge方法进行匹配的,属性名是personAge -->
address = ${person.address.city}
<hr>

<%
    List<Person> personList = new ArrayList<>();
    Person p1 = new Person("zhangsan");
    Person p2 = new Person("lisi");
    personList.add(p1);
    personList.add(p2);
    request.setAttribute("personList", personList);
%>
<b>获取List中的数据:</b><br>
person1 name = ${personList[0].name}<br>
person2 name = ${personList[1].name}<br>
<hr>

<b>遍历List中的数据:</b><br>
<c:forEach var="p" items="${personList}">
    name=${p.name}<br>
</c:forEach>
<hr>

<%
    Map<String, String> map = new HashMap<>();
    map.put("aaa", "aaa");
    map.put("bbb", "bbb");
    map.put("111", "111");
    request.setAttribute("map", map);
%>
<b>获取Map中的数据:</b><br>
${map.aaa}<br>
${map.bbb}<br>
${map["111"]} <!-- 数字不能使点号获取,需要使用[]获取。如果出现不能用点号获取数据的情况,可使用[]获取 -->
<hr>

<b>遍历Map中的数据:</b><br>
<c:forEach var="entry" items="${map}" >
    ${entry.key} = ${entry.value}<br>
</c:forEach>
</body>
</html>

运行结果:

 

 1.2 执行运算

语法:${运算表达式},EL支持如下运算符:

  • 算数运算符: +、-、*、/、%
  • 关系运算符: ==、!=、<、>、<=、>=,也可以使用eq、ne、 lt、gt、le、ge
  • 逻辑运算符:&&、|| 、!,也可以使用and、or、not
  • empty运算符:检查对象是否为空或者为null
  • 二元表达式: 表达式? value1 : value2
  • []和.号运算符

举例:

<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>运算符</title>
</head>
<body>
<%
    request.setAttribute("username","aaa");
    request.setAttribute("password","124");
%>

${username=='aaa' && password=='123' }

<br/>----------------empty运算符-------------------------<br/>

<%
    request.setAttribute("list1",null);
    request.setAttribute("list2",new ArrayList());
%>
${empty(list1)}<br>
${empty(list2)}


<br/>----------------二元运算符-------------------------<br/>
${user!=null ? user.username : '' }



<br/>----------------二元运算符(数据回显)-------------------------<br/>

<%
    request.setAttribute("gender","male");
%>

<input type="radio" name="gender" value="male"  ${gender=='male'?'checked':'' }><input type="radio" name="gender" vlaue="female" ${gender=='female'?'checked':'' }></body>
</html>

运行结果:

1.3 获取web开发的常用对象

EL表达式中定义了11个隐含对象,使用这些隐含对象可以很方便的获取web开发中的一些常见对象,并读取这些对象的数据。

语法:${隐式对象名称}

 

隐含对象的名称| 描述
pageContext JSP页面中的pageContext对象
pageScope 代表page域中用于保存属性的Map对象
requestScope 代表request域中用于保存属性的Map对象
sessionScope 代表sessionScope域中用于保存属性的Map对象
applicationScope 代表applicationScope域中用于保存属性的Map对象
param 表示一个保存了所有请求参数的Map对象
paramValues 表示一个保存了所有请求参数的Map对象,它对每个请求参数返回的是一个String[]
header 表示一个保存了所有请求头字段的Map对象
headerValues 表示一个保存了所有请求头字段的Map对象,对每个请求头字段返回一个String[]。如果头面有"-",例如Accept-Encoding,这要使用headerValues["Accept-Encoding"]
cookie 表示保存了所有cookie的Map对象
initParam 表示一个保存了所有web应用初始化参数的map对象

举例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL隐式对象</title>
</head>
<body>
${pageContext}

<br/>----------------使用el隐式对象访问指定的域-------------------------<br/>
<%
    pageContext.setAttribute("aa","11");
    request.setAttribute("bb", "22");
    session.setAttribute("cc", "33");
    application.setAttribute("dd", "44");
%>
${pageScope.aa}
${requestScope.bb}
${sessionScope.cc}
${applicationScope.dd}

<br/>----------------获取保存了所有请求参数的Map对象-------------------------<br/>
${param.name} 可以用于数据回显(使用reque跳转),分页的参数传递等<br>

${paramValues}
${paramValues.name[0]}
${paramValues.name[1]}

<br/>----------------获取请求头-------------------------<br/>
${header.connection}
${header['Accept-Language'] }<br>
${headerValues}

<br/>---------------获取cookie-------------------------<br/>
${cookie.JSESSIONID.name }<br/>
${cookie.JSESSIONID.value }<br>

<br/>---------------获取web应用初始化参数---------------<br/>
dbType=${initParam.dbType }

</body>
</html>

运行结果:

 

1.4 调用Java代码

EL表达式允许开发人员开发自定义函数,以调用Java类的方法。

示例:${prefix: method(params}

在EL表达式中调用的只能是Java类的静态方法

这个Java类的静态方法需要在TLD文件中描述,才可以个被EL表达式调用

EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。

1.4.1 EL函数的开发步骤:

一般来说,EL自定义函数开发与应用包括以下三个步骤:

  1. 编写一个Java类的静态方法
  2. 编写标签库描述符文件(tld),在tld文件中描述自定义函数
  3. 在JSP页面中导入和使用自定义函数

举例:

1. 增加一个类,并实现一个静态方法:

package com.utils;

public class StringUtils {
    public static String addTwoString(String s1, String s2) {
        return s1 + s2;
    }
}

2. 编写标签库描述符文件(tld),在tld文件中描述自定义函数

可以拷贝taglibs-standard-impl-1.2.5.jar中的fn.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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">

    <description>my functions library</description>
    <display-name>my functions</display-name>
    <tlib-version>1.1</tlib-version>
    <short-name>myfn</short-name>
    <!--定义当前文件的uri,用于在其他jsp中引用:<%@ taglib prefix="myfn" uri="/myELFunction" %> -->
    <uri>/myELFunction</uri>

    <!--使用<function>标签定义一个EL自定义函数 -->
    <function>
        <description>add two String</description>
        <name>addTwoString</name> <!-- 方法名称 -->
        <function-class>com.utils.StringUtils</function-class> <!-- 完整类名 -->
        <!-- 方法签名,也就是方法声明,必须致命方法的返回值类型以及各个参数的类型,各个参数之间使用逗号分隔 -->
        <function-signature>java.lang.String addTwoString(java.lang.String,java.lang.String)</function-signature>
    </function>

</taglib>

3. 在JSP页面中导入和使用自定义函数

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="myfn" uri="/myELFunction" %>
<html>
<head>
    <title>调用Java方法</title>
</head>
<body>
${myfn:addTwoString("aaa", "bbb")}
</body>
</html>

运行结果:

1.4.2 开发EL函数注意事项
编写完标签库描述文件后,需要将它放置到WEB-INF目录中或者WEB-INF目录下的处理classes和lib目录之外的任意子目录中。

TLD文件中的<uri>元素用来指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。

<function>元素用于描述一个EL自定义函数,其中:

  • <name>子元素用于指定EL自定义函数的名称。
  • <function-class>子元素用于指定`完整的Java类名`。
  • <function-signature>子元素用于指定Java类中的静态方法签名,方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间使用逗号分隔。

1.4.3 扩展:显示登录用户的另一种方式(不使用if标签)

<%@ page import="javabean.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="myfn" uri="/myELFunction" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
<%
    User user = new User();
    user.setUsername("zhangsan");
    session.setAttribute("user", user);
%>
<!-- el表达式中字符串不能使用+连接,需要自定义函数 -->
${user != null ? myfn:addTwoString("欢迎您:",user.username) : ''}
</body>
</html>

运行结果:

 

2.  SUN公司的EL函数库 

由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,SUN公司针对一些常见的处理定义了一套EL函数库供开发者使用。
在taglibs-standard-impl-1.2.5.jar的fn.tld中可以查看EL函数库的url和定义的函数。在其他JSP中导入即可使用:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
常见函数:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
    <title>EL函数库</title>
</head>
<body>
<br><b>------------contains方法-----------------------</b><br>
contains("abcd", "bc"): ${fn:contains("abcd", "bc")}
<br>------------containsIgnoreCase方法-------------<br>
containsIgnoreCase方法("abcd", "Bc"): ${fn:contains("abcd", "Bc")}

<br><b>------------escapeXml方法----------------------</b><br>
<c:set var="string1" value="This is first String."/>
<c:set var="string2" value="This <abc>is second String.</abc>"/>
使用 escapeXml() 函数:<br>
string (1) : ${fn:escapeXml(string1)}<br>
string (2) : ${fn:escapeXml(string2)}<br>
不使用 escapeXml() 函数:<br>
string (1) : ${string1}<br>
string (2) : ${string2}
<br><b>------------indexOf方法------------------------</b><br>
indexOf("www.baidu.com", "."): ${fn:indexOf("www.baidu.com", ".")}
<br><b>------------length方法-------------------------</b><br>
<!-- length 可以用于任何对象 -->
<%
    request.setAttribute("arr", new String[5]);
    request.setAttribute("str", "abcdefgh");
%>
arr.length: ${fn:length(arr)}<br>
str.length: ${fn:length(str)}
<br><b>------------replace方法------------------------</b><br>
replace("www,baidu,com", ",", "."): ${fn:replace("www,baidu,com", ",", ".")}
<br><b>------------split方法--------------------------</b><br>
split("2019-01-01", "-"): ${fn:split("2019-01-01", "-")}
<br><b>------------join方法---------------------------</b><br>
join(split("www,baidu,com"), "."): ${fn:join(fn:split("www,baidu,com", ","), ".")}
<br><b>------------startsWith方法---------------------</b><br>
startsWith("abcd", "ab"): ${fn:startsWith("abcd", "ab")}
<br><b>------------endsWith方法-----------------------</b><br>
endsWith("abcd", "bcd"): ${fn:endsWith("abcd", "bcd")}
<br><b>------------substring方法----------------------</b><br>
substring("0123456789", 2, 4) : ${fn:substring("0123456789", 2, 4)}
substring("0123456789", 2, -1) : ${fn:substring("0123456789", 2, -1)}
<br><b>------------substringAfter方法-----------------</b><br>
substringAfter("2019-01-01", "-"): ${fn:substringAfter("2019-01-01", "-")}
<br><b>------------substringBefore方法----------------</b><br>
substringBefore("2019-01-01", "-"): ${fn:substringBefore("2019-01-01", "-")}
<br><b>------------toLowerCase方法--------------------</b><br>
toLowerCase("aBcD"): ${fn:toLowerCase("aBcD")}
<br><b>------------toUpperCase方法--------------------</b><br>
toUpperCase("aBcD"): ${fn:toUpperCase("aBcD")}
<br><b>------------trim方法---------------------------</b><br>
trim("   ab cd ef gh   "): ${fn:trim("   ab cd ef gh   ")}
<br><b>---------------取出用户填写的爱好回显------------------</b><br>
<%
    request.setAttribute("likes",new String[]{"football","sing"});
%>

<input type="checkbox" name="likes" value="sing" ${fn:contains(fn:join(likes,","),"sing")?'checked':'' }>唱歌
<input type="checkbox" name="likes" value="dance" ${fn:contains(fn:join(likes,","),"dance")?'checked':'' }>跳舞
<input type="checkbox" name="likes" value="basketball" ${fn:contains(fn:join(likes,","),"basketball")?'checked':'' }>篮球
<input type="checkbox" name="likes" value="football" ${fn:contains(fn:join(likes,","),"football")?'checked':'' }>足球
</body>
</html>

运行结果:

 

posted @ 2019-07-06 18:34  暴躁的毛毛熊  阅读(353)  评论(0编辑  收藏  举报