2023.10.25
EL表达式是什么?
EL表达式,Expression Language(表达式语言),可以代替JSP中的java代码,让JSP文件中的程序看起来更加整洁,美观。 由于JSP中夹杂着各种java代码,例如<% java代码 %>、<%=%>等,导致JSP文件很混乱,不好维护,所以才有了EL表达式。EL表达式可以算是JSP语法的一部分,EL表达式归属于JSP。
ps:EL表达式一般操作的都是域对象中的数据,操作不了局部变量。
EL表达式优先从小范围中读取数据:pageContext < request < session < application
EL表达式的使用
EL表达式的作用:
从某个作用域中取数据,然后将其转换成字符串,然后将其输出到浏览器。
1、从某个域中取数据。
-
pageContext
-
request
-
session
-
application
2、将取出的数据转成字符串。
-
如果是一个java对象,也会自动调用java对象的toString方法将其转换成字符串。
3、将字符串输出到浏览器。
-
和这个一样:<%= %>,将其输出到浏览器。
EL表达式的基本语法格式:
${表达式}
EL表达式的使用案例:
<%
// 创建User对象
User user = new User();
user.setUsername("jackson");
user.setPassword("1234");
user.setAge(50);
// 将User对象存储到某个域当中。一定要存,因为EL表达式只能从某个范围中取数据。
// 数据是必须存储到四大范围之一的。
request.setAttribute("userObj", user);
%>
使用EL表达式取出User对象:
${userObj}
//等同于java代码:<%=request.getAttribute("userObj")%>
ps:面试题: ${userObj} 和 ${"userObj"}的区别是什么?
${userObj}表示从某个域中取出数据,并且被取的这个数据的name是"userObj",之前一定有这样的代码: 域.setAttribute("userObj", 对象);
${"userObj"} 表示直接将"userObj"当做普通字符串输出到浏览器。不会从某个域中取数据了。
如何输出对象的属性值?
${userObj.username} 使用这个语法的前提是:User对象有getUsername()方法。
${userObj.password} 使用这个语法的前提是:User对象有getPassword()方法。
${userObj.age} 使用这个语法的前提是:User对象有getAge()方法。
${userObj.email} 使用这个语法的前提是:User对象有getEmail()方法。
EL表达式中的 . 这个语法,实际上调用了底层的getXxx()方法。
注意:如果没有对应的get方法,则出现异常。报500错误。
EL表达式对null进行了预处理。如果是null,则向浏览器输出一个空字符串。
EL表达式中有四个隐含的隐式的范围:
-
pageScope 对应的是 pageContext范围。
-
requestScope 对应的是 request范围。
-
sessionScope 对应的是 session范围。
-
applicationScope 对应的是 application范围。
怎么从Map集合中取数据:
${map.key}
怎么从数组和List集合中取数据:
-
${数组[0]}
-
${数组[1]}
-
${list[0]}
忽略EL表达式的指令:
<%@page contentType="text/html;charset=UTF-8" isELIgnored="true" %>
isELIgnored="true" 表示忽略EL表达式
isELIgnored="false" 表示不忽略EL表达式。(这是默认值)
isELIgnored="true" 这个是全局的控制。
可以使用反斜杠进行局部控制:\${username} 这样也可以忽略EL表达式。
通过EL表达式获取应用的根:
-
${pageContext.request.contextPath}
ps:EL表达式没有内置request对象,所以不能直接用request获取应用的根,需要先用内置对象pageContext先获取request。
JSTL标签库
什么是JSTL标签库?
Java Standard Tag Lib(Java标准的标签库)。通常结合EL表达式一起使用。目的是让JSP中的java代码消失。
使用JSTL标签库的步骤:
- 引入JSTL标签库对应的jar包。 在WEB-INF下新建lib目录,然后将jar包拷贝到lib当中。ps:这里解释一下为什么有的jar包放在lib下(如mysql的驱动jar包和JSTL标签库jar包),有的jar包是在idea的设置中部署(如servlet-api.jar、jsp-api.jar):直接在idea中部署的jar包,是Tomcat服务器本身就有的jar包,这里部署只是为了和idea关联起来。 而放在lib下的jar包,是第三方的jar包,Tomcat服务器没有自带的。
- 在JSP中引入要使用标签库。(使用taglib指令引入标签库。)
- 在需要使用标签的位置使用即可。表面使用的是标签,底层实际上还是java程序。
JSTL标签的原理:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
以上uri后面的路径实际上指向了一个xxx.tld文件。
tld文件实际上是一个xml配置文件。
在tld文件中描述了“标签”和“java类”之间的关系。
以上核心标签库对应的tld文件是:c.tld文件。它在哪里。
在jakarta.servlet.jsp.jstl-2.0.0.jar里面META-INF目录下,有一个c.tld文件。
使用JSTL标签库的案例 :
<%@ page import="jsp.Student" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
// 创建List集合
List<Student> stuList = new ArrayList<>();
// 创建Student对象
Student s1 = new Student("3", "艾弗森");
Student s2 = new Student("24", "科比");
Student s3 = new Student("23", "乔丹");
// 添加到List集合中
stuList.add(s1);
stuList.add(s2);
stuList.add(s3);
// 将list集合存储到request域当中
request.setAttribute("stuList", stuList);
%>
//需求:将List集合中的元素遍历。输出学生信息到浏览器
//使用java代码实现
<%
// 从域中获取List集合
List<Student> stus = (List<Student>)request.getAttribute("stuList");
// 编写for循环遍历list集合
for(Student stu : stus){
%>
id:<%=stu.getId()%>,name:<%=stu.getName()%><br>
<%
}
%>
<hr>
//使用jstl标签库实现
//使用core标签库中forEach标签。对List集合进行遍历
//EL表达式只能从域中取数据。
//var后面的名字是随意的。var属性代表的是集合中的每一个元素。
<c:forEach items="${stuList}" var="s">
id:${s.id},name:${s.name} <br>
</c:forEach>
上述案例分别演示了使用和不使用jstl标签库来对集合中的元素进行遍历,访问服务器结果如下: