- 2.8.1 EL表达式介绍
- 2.8.2 EL表达式获取数据
- 2.8.3 EL表达式注意事项
- 2.8.4 EL表达式运算符
- 2.8.5 EL表达式使用细节
- 2.8.6 EL表达式中隐式对象
EL(expression Language): 表达式语言
它是在JSP2.0规范中加入的内容,也是Servlet规范的一部分。
它的作用是,在JSP页面中获取数据。让我们的JSP脱离Java代码块和JSP表达式。
语法:${表达式内容}
举个例子,
先向请求域中添加username数据
<% request.setAttribute("username","zhangsan"); %>
我们可以通过Java代码块获取:
<% out.println(request.getAttribute("username")); %>
也可以通过JSP表达式来获取:
<%= request.getAttribute("username") %>
现在我们用EL表达式获取是这样的:
${username}
相比前面的方式,EL表达式明显简单很多。
我这里有个疑问是,难道就直接这么写吗,不需要区分是哪个域对象吗?或者说,除了request对象,有没有可能是HttpSession对象?
那这里要说明一下,通过EL表达式这种获取数据的方式,我们并不需要区分式哪个域对象,只要我们这四大域中有这个数据,比如这个数据叫username,它就可以获取到。
这个直接看代码吧
<%@ page import="com.symc.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2021/11/7
Time: 21:12
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
EL表达式获取不同类型数据
<%--1.获取基本数据类型--%>
<% pageContext.setAttribute("num",10); %>
基本数据类型:${num}
<%--2.获取自定义对象类型--%>
<%--首先自己先创建一个对象,我这里用Student,封装并实现构造器和get、set方法--%>
<%
pageContext.setAttribute("stu",new Student("张三",15));
%>
<%-- 对于调用对象的属性,使用的是 对象名.属性名 的方式--%>
<%-- 注意这里的实现原理是调用封装对象中的get方法,不能混淆--%>
自定义对象:${stu}
学生姓名:${stu.name}
学生年龄:${stu.age}
<%--3.获取数组类型--%>
<%
String[] arr = {"Hello","World"};
pageContext.setAttribute("a",arr);
%>
数组arr:${a}
0索引元素:${a[0]}
1索引元素:${a[1]}
<%--4.获取List集合--%>
<%
ArrayList list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
pageContext.setAttribute("list",list);
%>
List集合:${list}
<%-- 由于ArrayList底层是由数组实现的,所以可以通过下标的方式获取--%>
0索引元素:${list[0]}
<%--5.获取Map集合--%>
<%
HashMap map = new HashMap<>();
map.put("zhangsan",new Student("张三",23));
map.put("lisi",new Student("李四",23));
pageContext.setAttribute("map",map);
%>
Map集合:${map}
第一个学生对象:${map.zhangsan}
第一个学生对象姓名:${map.zhangsan.name}
浏览器是这样的:
1.EL表达式没有空指针异常
2.EL表达式没有索引越界异常
3.EL表达式没有字符串的拼接
还是拿上面的代码来演示,
这次我们不去创建对象,
自定义对象:${stu2}
显示:
这说明可以访问空对象但是不报异常。
再来看,数组长度只为2,我们去访问一下不存在的索引8
数组arr:${a}
0索引元素:${a[0]}
1索引元素:${a[1]}
8索引元素:${a[8]}
显示:
这说明EL表达式没有索引越界异常。
再看看字符串的拼接,就用刚才的数组,我这里有两种方式
${a[0]+a[1]}
${a[0]}+${a[1]}
显示:
针对 ${a[0]+a[1]}这种方式的它直接报错。
再看看对于
a
[
0
]
+
{a[0]}+
a[0]+{a[1]}的方式
发现字符串连+也一起输出来了,所以字符串拼接再EL表达式中是不可用的。
关系运算符
逻辑运算符
其他运算符
对于empty举例:
<%--empty--%>
<%
String str1 = null;
String str2 = "";
int[] arr = {};
%>
${empty str1}
${empty str2}
${empty arr}
对于三目运算符举例:
<%--三目运算符。获取性别的数据,在对应的按钮上进行勾选--%>
<%
pageContext.setAttribute("gender", "men");
%>
男
女
效果:
EL表达式能够获取四大域对象的数据,根据名称从小到大在域对象中查找。
还可以获取JSP其他八个隐式对象,并调用对象中的方法。
对于获取四大域对象中的数据:
<%--获取四大域对象中的数据--%>
<%
pageContext.setAttribute("username","张三");
request.setAttribute("username","李四");
// session.setAttribute("username","王五");
// application.setAttribute("username","张");
%>
${username}
显示:
它在四大域中是逐个查找的,从pageContext到application。
我这里还总结了,当我们的不同域中有相同的名称,作用范围小获取数据的优先级高。
比如说,在PageContext域中和HttpRequest域中,页面域仅仅作用在当前页面中,作用范围是最小的,而请求域作用在一次请求或请求转发中,要比页面域大,可以这么理解吧,作用范围越小,说明越精确,我们获取这个username名称的数据,获取到的是pageContext对象中的数据。另外,复习一下HttpSession域是会话域,作用在多次请求中,Application是应用域,作用在整个应用中。所以优先获取数据的顺序是
pageContext>request>session>application
对于获取JSP中其他八个隐式对象,这里举例获取虚拟目录名称
<%--获取虚拟目录名称--%>
<%=request.getContextPath()%>
${pageContext.request.getContextPath}
显示:
<%--pageContext对象 可以获取其他3个域对象和JSP中八个隐式对象--%>
${pageContext.request.contextPath}
<%--applicationScope sessionScope requestScope pageScope 操作四大域对象中的数据--%>
<%
request.setAttribute("username","zhangsan");
%>
${username}
${requestScope.username}
<%--header headValues 获取请求头数据--%>
${header["connection"]}
${headerValues["connection"][0]}
<%--param paramValues 获取请求参数数据--%>
${param.username}
${paramValues.hobby[0]}
${paramValues.hobby[1]}
<%--initParam 获取全局配置参数--%>
${initParam["pname"]}
<%--cookie 获取cookie信息--%>
${cookie}<%--获取的是Map集合--%>
${cookie.JSESSIONID}<%--获取Map集合第二个元素--%>
${cookie.JSESSIONID.name}<%--获取cookie对象的名称--%>
${cookie.JSESSIONID.value}<%--获取cookie对象的值--%>



