本文被 系统学习JavaWeb 收录点击订阅专栏
何为EL表达式?
EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。
EL表达式主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出。
下面来浅浅感受一下EL表达式的简洁:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
request.setAttribute("key", "值");
%>
表达式脚本输出key的值: <%=request.getAttribute("key")%><br/>
EL表达式输出key的值: ${key}
</body>
</html>
需要注意的是,使用表达式脚本的时候,若原key无值,则会显示null;而当使用EL表达式的时候,若原key无值,则不显示。
回顾一下上节关于jsp域对象的知识
域对象是可以像Map一样存取数据的对象,四个域对象的功能一样,区别是对数据的存取范围。
下表列举了四个域对象和作用范围
对象 | 作用范围 |
---|---|
pageContext(PageContextImpl类) | 当前jsp页面范围 |
request(HttpServletRequest类) | 一次请求内 |
session(HttpSession类) | 一个会话范围内(打开浏览器访问服务器,直到关闭浏览器) |
application(ServletContext类) | 整个web工程范围内有效(只要web工程不停止,数据都在) |
在EL表达式中也一样,当四个域中都有相同的key数据时,EL表达式会根据这四个域的从小到大顺序去搜索,找到就输出, 优先级从小到大顺序:
JavaBean(是java类)是一种JAVA语言写成的可重用组件(Component)。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。
一个JavaBean由3部分组成:
首先,我们先创建一个学生类,包括相应的set、get方法:
Student.java
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author 兴趣使然黄小黄
* @version 1.0
*/
public class Student {
private String name;
private int age;
private String[] phones;
private List<String> cites;
private Map<String, Object> map;
public Student() {
}
public Student(String name, int age, String[] phones, List<String> cites, Map<String, Object> map) {
this.name = name;
this.age = age;
this.phones = phones;
this.cites = cites;
this.map = map;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getPhones() {
return phones;
}
public void setPhones(String[] phones) {
this.phones = phones;
}
public List<String> getCites() {
return cites;
}
public void setCites(List<String> cites) {
this.cites = cites;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", phones=" + Arrays.toString(phones) +
", cites=" + cites +
", map=" + map +
'}';
}
}
jsp代码及EL表达式如下:
<%@ page import="com.hxh.expressionlanguage.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %><%--
Created by IntelliJ IDEA.
User: 26510
Date: 2022/10/24
Time: 10:31
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Student student = new Student();
student.setName("黄小黄");
student.setPhones(new String[]{"15325367485", "18811026589"});
List<String> cites = new ArrayList<>();
cites.add("北京");
cites.add("上海");
cites.add("天津");
cites.add("西安");
student.setCites(cites);
Map<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
student.setMap(map);
//存放到域对象中
pageContext.setAttribute("s", student);
%>
<%-- EL表达式获取值,并输出 --%>
输出student: ${s}<br>
输出student的name: ${s.name}<br>
输出student的phones数组的值: ${s.phones[0]}<br>
输出student的cites集合中的元素: ${s.cites}<br>
输出student的map集合: ${s.map}<br>
输出Map集合中某个key值: ${s.map.key1}<br>
</body>
</html>
注意事项:
EL表达式输出对象值,不是直接查找对应的属性,而是通过对应属性的get方法获取值, 也就是说,如果只声明了属性,而没有在对应类中提供相应的get方法,则无法通过EL表达式获取该属性值!
语法格式如下:
${运算表达式}
empty运算可以判断一个数据是否为空,若为空,输出true,不为空,输出false。 以下几种情况为空(在原本的key之前加empty关键字):
表达式 1?表达式 2:表达式 3
表达式1为真返回表达式2的值,表达式1为假返回表达式3的值
示例代码及结果如下:
<body>
<%
//1、值为null值时
request.setAttribute("emptyNull", null);
//2、值为空串时
request.setAttribute("emptyStr", "");
//3、值是Object类型数组,长度为零的时候
request.setAttribute("emptyArr", new Object[]{});
//4、list集合,元素个数为零
List<String> list = new ArrayList<>();
request.setAttribute("emptyList", list);
//5、map集合,元素个数为零
Map<String,Object> map = new HashMap<String, Object>();
request.setAttribute("emptyMap", map);
//6、其他类型数组长度为0
request.setAttribute("emptyIntArr", new int[]{});
%>
${ empty emptyNull } <br/>
${ empty emptyStr } <br/>
${ empty emptyArr } <br/>
${ empty emptyList } <br/>
${ empty emptyMap } <br/>
${ empty emptyIntArr} <br/>
<%-- 三元运算 --%>
${ 12 != 12 ? "相等":"不相等" }
</body>
中括号运算可以输出Map集合中key里含有特殊字符的key的值
特殊字符:等于、大于小于、点等。
示例代码如下:
<body>
<%
Map<String,Object> map = new HashMap<String, Object>();
map.put("a.a.a", "aaaValue");
map.put("b+b+b", "bbbValue");
map.put("c-c-c", "cccValue");
request.setAttribute("map", map);
%>
<%--特殊的key需要去掉最开始的"."并使用中括号和单引号(双引号)包起来--%>
${ map["a.a.a"] } <br> <%--如果不加中括号则相当于三个.运算--%> //错误的是 ${map.a.a.a}
${ map["b+b+b"] } <br> <%--如果不加中括号则相当于三个+运算--%>
${ map["c-c-c"] } <br> <%--如果不加中括号则相当于三个-运算--%>
</body>
EL表达式中的11个隐含对象是EL表达式自己定义的,可以直接使用。
<body>
<%
pageContext.setAttribute("key1", "pageContext1");
pageContext.setAttribute("key2", "pageContext2");
request.setAttribute("key2", "request");
session.setAttribute("key2", "session");
application.setAttribute("key2", "application");
%>
<%-- 获取特定域中的属性 --%>
${ pageScope.key1 } <br>
${ applicationScope.key2 }
<%-- 若直接获取key1或key2依然按照之前范围从小到大检索,无法获取指定域 --%>
</body>
pageContext常用于如下需求,在jsp的代码脚本中使用如下:
在EL表达式中 更加简便,实现上述需求的代码如下:
<body>
<%-- 先通过pageContext对象获取request、session对象,再获取以下内容 --%>
1.协议: ${ pageContext.request.scheme }<br>
2.服务器ip:${ pageContext.request.serverName }<br>
3.服务器端口:${ pageContext.request.serverPort }<br>
4.获取工程路径:${ pageContext.request.contextPath }<br>
5.获取请求方法:${ pageContext.request.method }<br>
6.获取客户端ip地址:${ pageContext.request.remoteHost }<br>
7.获取会话的id编号:${ pageContext.session.id}<br>
</body>
看到这里,是不是会感到困惑?
不是说EL表达式会更加简洁吗,为何在获取的时候语句长度反而比代码脚本要复杂呢?
在实际开发中,有一个小技巧,代码示例如下:
<body>
<%
pageContext.setAttribute("req", request);
pageContext.setAttribute("session", session);
%>
1.协议: ${ req.scheme }<br>
2.服务器ip:${ req.serverName }<br>
3.服务器端口:${ req.serverPort }<br>
4.获取工程路径:${ req.contextPath }<br>
5.获取请求方法:${ req.method }<br>
6.获取客户端ip地址:${ req.remoteHost }<br>
7.获取会话的id编号:${ session.id}<br>
</body>
提前将对应的对象设置成域对象,便于EL表达式访问,可以使代码更简洁!
<body>
获取请求参数username的值:${ param.username } <br>
获取请求参数password的值:${ param.password } <br>
获取请求参数中第一个hobby的值:${ paramValues.hobby[0] } <br>
获取请求参数中第二个hobby的值:${ paramValues.hobby[1] } <br>
<%-- 有多个同名的key时使用paramValues的索引值决定获取哪一个,使用param只可获取第一个 --%>
使用param获取hobby的值:${ param.hobby } <br>
</body>
<body>
输出请求头[user-Agent]的值:${ header["User-Agent"] }<br>
输出请求头中第一个[user-Agent]的值:${ headerValues["User-Agent"][0] }<br>
</body>
<body>
获取Cookie的名称:${ cookie.JSESSIONID.name } <br>
获取Cookie的值:${ cookie.JSESSIONID.value } <br>
</body>
<body>
输出<Context-param>username的值:${ initParam.username } <br>
输出<Context-param>url的值:${ initParam.url } <br>
</body>
本文部分内容参考:尚硅谷JavaWeb课程。好了,本文内容到这里就告一段落了,欢迎大家订阅专栏,加入JavaWeb学习!点击订阅
部分图片出处:EL表达式 @CSDN early_day