EL表达式(Expression Language)
作用:从作用域中(page,request,session,ServletContext,pageContext)取值,并显示在页面中。
本质:用于替换输出脚本<%= %>
1. 如何从作用域中取值(基本类型或者是字符串类型)
request.setAttribute(“name”, “suns”);
${requestScope.name} 从request作用域中取值,其中name是命名属性的名字,最终将命名属性的值输出在页面中。

注意:EL表达式获取命名属性时,若命名属性不存在,则不显示任何内容,而输出脚本<%= %>获取命名属性时,若命名属性不存在,则显示null。

使用EL表达式从session作用域中取值:
session.setAttribute(“name”, “suns”);
${sessionScope.name}
使用EL表达式从ServletContext作用域中取值:
application.setAttribute(“name”, “suns”);
${applicationScope.name}
使用EL表达式从pageContext作用域中取值:
pageContext.setAttribute(“name”, “suns”);
${pageScope.name}
注意:我们再看一种情况,EL表达式从作用域中取值的简便写法:
${name}直接写命名属性的名字,这种情况代表EL表达式会从pageContext作用域开始,依次查找request作用域,session作用域,ServletContext作用域。如果发现存在name命名属性,则直接返回。作用域从小到大一次查找:
pageContext --> request --> session --> ServletContext(application)
2. 从作用域中获取对象类型的内容进行显示
request.setAttribute(“user”, user);
${requestScope.user.name} 获取user对象中的getName()方法返回值
${requestScope.user.password} 获取user对象中的getPassword()方法返回值

我们访问jsp页面后,在网页上显示的内容是:

注意:
EL表达式:${requestScope.user.name},我们在EL表达式中对user对象做”.”操作,并不是直接访问user对象的name属性,User类中的name属性已经做了封装,我们是不可能直接访问这个name属性的,这个”.”操作其实是调用了user对象的getName()方法。
我们可以来验证一下这个事儿,我们把User中的getName()方法注释掉,我们再来访问这个页面,页面出错了:

我们还要注意:EL表达式只认getXXX()方法,不认XXX是不是这个对象的属性。我们上面说了,比如:我们在User类中写一个方法:
public int getNextPage(){
return 10;
}
但是User这个类中没有nextPage这个属性,这时,我们仍然可以在EL表达式中获取nextPage的值:
<h1>${requestScope.user.nextPage}</h1> ---> 显示在页面的结果是10
“.”运算符代表调用get方法,如果”.”后面是name,EL表达式就会调用getName()方法。如果”.”后面是nextPage,EL表达式就会调用getNextPage()方法。
EL的运算符
1. 算术运算符 + - * / %
注意:
1. 算术运算符和Java的加减乘除相同,但是”+”不能用来连接字符串,即${“abc” + “def”}这是错误的。
2. EL表达式不区分整数和小数(10/3 结果为小数)。

2. 比较运算符 > >= < <= == !=
注意:在EL表达式中做字符串内容的比较,用==即可(不同于Java,Java中做字符串内容的比较要用equals方法)。
在EL表达式中关系运算符还可以用特殊符号表示:
大于:gt对应 > 小于:lt对应 < 等于:eq对应 ==
大于等于:ge对应 >= 小于等于:le对应 <=
不等于:ne对应 !=
例如:${10 gt 3} 最后页面输出true

3. 逻辑运算符 && || !(EL中没有&和|)
${true && true} 页面显示true
${false || false} 页面显示false
${! false} 页面显示true

4. empty运算符
作用:用于判断这个命名属性是否存在,或者说,判断EL表达式中的表达式是否为空。
注意:
1. 因为是判断是否为空,所以,为空的时候返回true,不为空的时候返回false。
2. 字符串对象如果值是空串””,empty会判断为空。创建一个集合对象但是没有向集合中添加元素,empty也会判断该集合对象为空。
${empty requestScope.name} -- 返回true说明request作用域中没有name命名属性,返回false说明不为空,也就是request作用域中存在叫做name的命名属性。

4. EL表达式中的特殊内置对象
1. pageContext【重要,在jsp中也是内置对象】
特点:在EL表达式中的特点和在jsp中的特点是一样的。可以获得其他8种jsp的内置对象。但是我们更常用的一个功能是在jsp页面中用EL表达式获取应用名:
我们以前在jsp页面中使用脚本来获取应用名:
<%=request.getContextPath()%> //动态获取应用名
现在,我们想象一下,我们有pageContext这个内置对象,我们获得应用名应该是:pageContext.getRequest().getContextPath();
我们转换为EL表达式就应该是:
${pageContext.request.contextPath}我们之前说过,”.”运算就是调用get方法。
EL表达式获取应用名和输出脚本获取应用名是等价的,因为脚本是不建议使用的,所以我们用EL表达式替换掉脚本。
2. param【用处不大,因为我们通常都是用Servlet来接收数据】
可以在EL表达式中获取用户client提交的数据
Client提交数据: 1 地址栏 2 超级链接 3 表单
地址栏:http://IP:Port/应用名/资源名?name=suns&password=123
超级链接:<a href=”/应用名/资源名?name=suns&pwd=111”></a>
表单:<input type=”text” name=”name”/>
Servlet中获取数据:
request.getParameter(“name”);
EL表达式获取数据:${param.name}

注意:还有一个paramValues,我们用EL表达式获取请求实体数据的时候,可以用paramValues来获取同键对应多值的参数。返回的是一个String类型的数组,可以通过角标直接获取。


拓展:
当我们在浏览器中访问jsp页面时,浏览器出现了下载现象,这时我们就要检查contentType属性是不是写错了:

当我们把contentType属性写错的时候,访问时浏览器就会弹出下载窗口。
3. header
作用:header可以用来获取请求头数据。
${header} 以键值对形式,返回所有的请求头数据。
${header[“键名”]} 返回指定键的请求头数据。
${headerValues[“键名”]}

4. cookie
作用:可以在EL表达式中直接获得cookie的内容。
用法:
${cookie} 以键值对形式返回请求中的所有cookie对象(在返回的键值对中,key是cookie对象中的键的名字,value是cookie对象)
${cookie.JSESSIONID} 返回存储JSESSIONID的cookie对象(JSESSIONID是cookie对象中的键的名字)
${cookie.JSESSIONID.name} 返回cookie对象中的key
${cookie.JSESSIONID.value} 返回cookie对象中的value
我们之前的Cookie编程是这样的:


