发布于2026-07-22 阅读(0)
扫一扫,手机访问
先说说EL表达式是什么。全称Expression Language,也就是表达式语言。它的核心作用很简单——替代JSP页面里那些繁琐的表达式脚本,帮我们更优雅地输出数据。
相比JSP原本的表达式脚本,EL表达式无疑简洁得多。它的格式也非常直观:${表达式}。注意,EL表达式是写在JSP页面中的,而表达式里通常放的是域对象的key。
来看个例子。在web目录下创建一个Test.jsp:
<%
request.setAttribute("key", "value");
%>
<%-- 表达式脚本输出key1的值 --%>
<%=request.getAttribute("key1")%>
<%-- EL表达式输出key1的值 --%>
${key1}
<%-- 表达式脚本输出null值时页面显示null
EL表达式输出null值时页面什么都不显示(空串)--%>
运行结果:

看到区别了吗?当值为null时,表达式脚本会在页面上显示"null"字样,而EL表达式则直接输出空串,页面干净不少。
EL表达式主要用来输出域对象中的数据。这里有个关键点:如果四个域对象(pageContext、request、session、application)中都有同一个key的值,EL表达式会按照域对象的范围从小到大进行搜索——找到就输出,与四个域对象声明的先后顺序无关。
代码演示一下:
<%
//向四个域对象中都保存相同key的值
request.setAttribute("key", "request");
session.setAttribute("key", "session");
application.setAttribute("key", "application");
pageContext.setAttribute("key", "pageContext");
%>
<%-- 使用EL表达式输出key的值 --%>
${key}
运行结果:

结果输出的是"pageContext",因为pageContext的域范围最小,优先被搜索到。
在实际开发中,我们经常需要输出Ja va对象的属性。这里有个非常重要的细节需要搞清楚:EL表达式中对象名.属性名,并不是直接去找属性值,而是找名字对应的getXxx方法(或者isXxx方法)。没有这个方法就会报错。
先创建一个Person类:
public class Person {
private String name;
private String[] phones;
private List cities;
private Map map;
//没有声明age属性
public int getAge() {
return 18;
}
//以及全参、空参构造器,各属性的getter/setter方法
}
注意,Person类中并没有声明age属性,但定义了getAge()方法。这在EL表达式中就能通过${p.age}访问到,因为EL找的是getter方法。
演示一下具体用法:
<%
Person person = new Person();
person.setName("JayChou");
person.setPhones(new String[]{"123","456","789"});
List cities = new ArrayList();
cities.add("北京");
cities.add("上海");
cities.add("深圳");
person.setCities(cities);
Map map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
person.setMap(map);
pageContext.setAttribute("p", person);
%>
输出Person:${ p }
输出Person的name属性:${p.name}
输出Person的phones数组地址值:${p.phones}
输出Person的phones数组属性值:${p.phones[2]}
输出Person的cities集合中的元素值:${p.cities}
输出Person的List集合中个别元素值:${p.cities[2]}
输出Person的Map集合: ${p.map}
输出Person的Map集合中某个key的值: ${p.map.key1}
输出Person的age值:${p.age}
运行结果:

从输出可以看到,${p.phones}输出的是数组的地址值,要获取具体元素需要通过索引${p.phones[2]}。而${p.age}虽然类中没有age属性,但因为存在getAge()方法,依然能正确输出18。
EL表达式不仅能用${表达式}输出数据,还支持各种运算。语法是${运算表达式},支持的运算符很丰富:



empty运算用来判断一个数据是否为空。为空时输出true,不为空输出false。以下几种情况会被判定为空(在key之前加empty关键字):
(1)值为null、空串
(2)值为Object类型的数组且长度为0(注意:其他类型的长度为0的数组值为非空)
(3)List、Map集合元素个数为0
格式:表达式1 ? 表达式2 : 表达式3
表达式1为真时返回表达式2的值,为假时返回表达式3的值。
来看个综合演示:
<%
request.setAttribute("emptyNull", null);
request.setAttribute("emptyStr", "");
request.setAttribute("emptyArr", new Object[]{});
List list = new ArrayList<>();
request.setAttribute("emptyList", list);
Map map = new HashMap();
request.setAttribute("emptyMap", map);
request.setAttribute("emptyIntArr", new int[]{});
%>
${ empty emptyNull }
${ empty emptyStr }
${ empty emptyArr }
${ empty emptyList }
${ empty emptyMap }
${ empty emptyIntArr}
${ 12 != 12 ? "相等":"不相等" }
运行结果:

注意看${ empty emptyIntArr }输出的是false,因为int[]不是Object类型数组,即使长度为0也不被视为空。
点运算用来输出对象某个属性的值(通过getXxx或isXxx方法)。中括号运算则用来输出有序集合中某个元素的值。
这里有个实用技巧:中括号运算可以输出Map集合中key里含有特殊字符的值。来看个例子:
<%
Map map = new HashMap();
map.put("a.a.a", "aaaValue");
map.put("b+b+b", "bbbValue");
map.put("c-c-c", "cccValue");
request.setAttribute("map", map);
%>
${ map['a.a.a'] }
${ map["b+b+b"] }
${ map['c-c-c'] }
运行结果:

如果直接用${map.a.a.a},系统会理解为三次点运算,结果自然不对。所以遇到key中包含特殊字符的情况,一定要用中括号加引号的方式。
EL表达式自带了11个隐含对象,可以直接使用,不需要额外声明。

咱们逐个来看这些隐含对象的使用方法。
(1)pageScope、requestScope、sessionScope、applicationScope
这四个对象用来获取特定域中的属性。当多个域中有相同key时,可用它们精确获取指定域的值:
<%
pageContext.setAttribute("key1", "pageContext1");
pageContext.setAttribute("key2", "pageContext2");
request.setAttribute("key2", "request");
session.setAttribute("key2", "session");
application.setAttribute("key2", "application");
%>
${ pageScope.key1 }
${ applicationScope.key2 }
运行结果:

如果直接写${key2},依然会按照域范围从小到大搜索,获取到的是pageContext域中的值。使用applicationScope则能精确获取application域中的值。
(2)pageContext对象
pageContext对象可以获取request、session等内置对象,进而获取更多信息:
1.协议:${ pageContext.request.scheme }
2.服务器ip:${ pageContext.request.serverName }
3.服务器端口:${ pageContext.request.serverPort }
4.获取工程路径:${ pageContext.request.contextPath }
5.获取请求方法:${ pageContext.request.method }
6.获取客户端ip地址:${ pageContext.request.remoteHost }
7.获取会话的id编号:${ pageContext.session.id}
运行结果:

(3)param、paramValues对象
这两个对象用来获取请求参数。param获取单个参数值,paramValues获取同名参数的所有值:
获取请求参数username的值:${ param.username }
获取请求参数password的值:${ param.password }
获取请求参数中第一个hobby的值:${ paramValues.hobby[0] }
获取请求参数中第二个hobby的值:${ paramValues.hobby[1] }
使用param获取hobby的值:${ param.hobby }
运行结果:
在浏览器地址栏输入:http://localhost:8080/MyTest/Test.jsp?username=Jaychou&password=123&hobby=sing&hobby=dance

多个同名参数时,param只获取第一个值,paramValues通过索引获取指定位置的值。
(4)header、headerValues对象
用来获取请求头信息:
输出请求头[User-Agent]的值:${ header["User-Agent"] }
输出请求头中第一个[User-Agent]的值:${ headerValues["User-Agent"][0] }
(5)cookie对象
用来获取Cookie信息:
获取Cookie的名称:${ cookie.JSESSIONID.name }
获取Cookie的值:${ cookie.JSESSIONID.value }
运行结果:

(6)initParam对象
用来获取web.xml中配置的上下文参数。首先在web.xml中配置参数(修改后需要重启服务才能生效):
username root url jdbc:mysql:///test
然后在JSP页面中获取:
输出username的值:${ initParam.username }
输出url的值:${ initParam.url }
运行结果:

掌握了这11个隐含对象,EL表达式用起来就游刃有余了。无论是获取请求参数、请求头、Cookie,还是读取配置参数,都能用简洁的表达式搞定。
上一篇:jsp的九大内置对象深入讲解
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8