5. JSP - 表达式语言 - EL
2022-05-31 17:17:12

EL,Expression Language,表达式语言,是一种在JSP页面中获取数据的简单方式,通过${变量名}的方式可以获取到值,

需要注意的是EL只能从 pageConext、request、session、application 四大域属性空间中获取数据。

 

用EL来获取上面所说的值:

先来个测试(失败案例),即获取不了num的值,因为num不是在pageContext、request、session、和 appliction中:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!--  这是一个错误的获取: -->
    <%! int sum = 999; %>
    ${ sum }
    <!--  虽然是一个错误的例子 , 但是在jsp中他不会报错! 也不会显示任何东西!! 记住el表达式这个特性!  -->
    
</body>
</html>

上面获取不了 也不会报错 也不会输出任何数据 , 记住这个特性!

  成功案例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% request.setAttribute("el", "我是el表达式!"); %>
    ${el}
    <!--  这样就会直接在页面显示 request中设置的el值了  : ‘我是el表达式’ -->
</body>
</html>

我刚试过了一下  它不可以打印多个值 ,即一个el 获取多个值 不然异常!

其实EL可以直接输出你想输出的内容 但是不是双引号  是单引号括起来 ,只能输出指定的 但 不能做算术运算哦!

 

 


 

问题来了! 就是说 如果我值都相等 那么el表达式会获取那个值呢:
  那么我们4个域都设置一样的名字 不一样的值 看他获取那个:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% 
    pageContext.setAttribute("name", "pageContext");
    request.setAttribute("name", "request");
    session.setAttribute("name", "session");
    application.setAttribute("name", "application");
    %>
    ${ name}
</body>
</html>

我们已经把它的4个域都设置名字都一样的了啊! 但是你会发现他打印的是pageContext 为什么?  因为:

EL底层是从最小范围的pageContext依次查找,直到查找到最大范围 application。这期间,只要查找到了,则直接获取,不再去后面的范围中查找了,若最终没有查找到,则什么也不输出。

所以说: 允许名字相同,但是输出优先级 是 作用域范围小的内置对象 - > 范围大的内置对象,一旦获取到了就不会往下找了,所以你可以尝试吧 pageContetx 注释 那么他会打印 request,其实我已经排好序了,作用域从小到大就是上面4个 上往下!

问题又来了! 那我如果名字都一样 需要打印指定的,那就需要:

 

 


 

那就需要你手动在${} 里面指定 使用域属性空间相关的内置对象获取数据 即:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <% 
    pageContext.setAttribute("name", "pageContext");
    request.setAttribute("name", "request");
    session.setAttribute("name", "session");
    application.setAttribute("name", "application");
    %>
    
    <%-- 其实呢 指定域的内置对象很容易记 就是 域名 + Scope 
            Scope :  范围  【skəʊp】
    --%>
    
    
    ${ pageScope.name }
    
    <br>
    
    ${ requestScope.name }
    
    <br>
    
    ${ sessionScope.name }

    <br>
    
    ${ applicationScope.name }
</body>
</html>

这里已经给出很详细了! 接下来:

el表达式 怎么访问 类中的属性:

如果存在sytudent对象 那么 我们想访问他的 name 或其他属性:

 

 


 

访问 Bean 的属性
EL 可以通过 ${key .属性}的方式获取到指定对象的属性值。其底层实际调用的是该对象的相应属性的 get 方法 (原理)。也可以使用${key[“属性”]的方式获取。该方式不常用(麻烦的要死)。

例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="test.Student"%>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    
    <%-- 如果有包 记得先导student的包! --%>
    <%
        Student stu = new Student("bi-hu"); //实例化一个student类 stu 对象
        request.setAttribute("stu", stu);    //然后把这个stu给塞进request中
    %>
    
    ${ requestScope.stu.name }
    <br>
    ${  requestScope.stu["name"] }
    
</body>
</html>

打印出来了  两个都是bi-hu 那你也可以用这两种访问去访问student 中其他属性 !

记得要装(setAttribute)对象进4大域其中一个域里!

问题又来了: 如果我一个类中包含另一个类,然后我想一层一层往下获取 那么得这样:

例:schooll 中 有 student ,【已经定义好 student 类 和  school 类! 】 我想获取学生的名字:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
   <%@ page import="test.*" %>
    

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    
    <%-- 如果有包 记得先导student 和 School的包! --%>
    <%
        School school = new School("青鸟北大");        //实例化一个学校类 school 名字是 青鸟北大
        Student bihu = new Student("bi-hu"); //实例化一个学生类 bihu 名字是 bihu
        school.setStu(bihu);            //把bihu这个学生设置到了 青鸟北大
        request.setAttribute("school", school);                //把学校塞进reqeust里面!
    %>
    
    ${ requestScope.school.stu.name }
    <br>
    ${  requestScope.school.stu["name"] }
    
</body>
</html>

其实都是用 . 的方法就可以逐步往下找了【类与对象也是这样的】 但是记住 往下找的时候 是: 学校.学生属性.学生姓名   这三都是一个属于学校类的 。

 

EL 表达式还可以:

 


 

获取数组中的元素
EL 可以通过 ${key[索引]} 的方式获取到指定索引的元素。不过,需要注意的是,若数组中不存在该指定索引的元素,系统并不会抛出数组越界异常(上面讲了 EL的特性)。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<% 
    int[] arr = {1,2,3,4,5};
    request.setAttribute("arr", arr);    
%>

${ arr[0] }    <%-- 或者: --%>
<br>
${ requestScope.arr[1]}



</body>
</html>

第一次获取的是第一个元素 第二次那个画蛇添足 获取第二个元素 ,带脑子思考!

 

EL表达式还可以获取List的元素:

与获取数组中的元素相同,通过 ${key[索引]} 的方式可以获取 List 中指定索引的元素。若 List 中不存在该指定索引的元素,系统并不会抛出越界异常。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,test.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<!--  首先定义个List 往里面添加几个学生  -->
<%
    Student stu = new Student("张三");
    Student stu1 = new Student("李四");
    Student stu2 = new Student("王五");
    Student stu3 = new Student("赵6");
    
    List<Student> list = new ArrayList();        //吧上面的学生装进容器
    list.add(stu);
    list.add(stu1);
    list.add(stu2);
    list.add(stu3);
    
    request.setAttribute("list_stu", list);        //把list装进request里面 key是 list_stu
%>

<!-- 输出个李四 -->
${ list_stu[1].name  }

<br>

<!-- 输出个赵6 -->
${ list_stu[3].name }

</body>
</html>

 

因为Set没有索引和顺序的感念,所以EL表达式不能输出Set

 


 

获取 Map 中的元素
EL 通过 ${key.mapKey} 的方式可以获取指定 mapKey 的指定 mapValue 的值。 别搞混!  这里的key  和 mapKey 是不一样的.

其实这个更容易 就是直接 .Mapkey  就可以获取到Map中key对应的值了!

  

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,test.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<!--  首先定义个List 往里面添加几个学生  -->
<%
HashMap<String,String> user = new HashMap<String,String>();
    user.put("a", "疼迅");
    user.put("b","阿狸");
    user.put("c", "美団");
    
    //老方法
    request.setAttribute("user_map", user);
%>

    ${  user_map.a}
    <br>
${  user_map.b}
<br>
${  user_map.c}

</body>
</html>

这个Map的key 不能为数值! 我也不知道为什么啊 我用Integer 也是不行! 会报错 ,意思是 ${user_map.1}  这句话服务器是解析不了的 我也不知道为什么 ....

 

 


 

运算符

EL 表达式可以进行各种运算,其中常用的运算符有:

  1. 算术运算符 + – * / % (不支持++、–)
  2. 关系运算符 == != > >= < <=
  3. 逻辑运算符 ! && || not and or
  4. 三目运算符 ? :
  5. 特殊运算符 empty

&& 或者 and, 例如:${false && false} 或者 ${false and false }
|| 或者 or, 例如:${true || false} 或者 ${true or false }
! 或者 not,例如:${!true} 或者 ${not true }

empty的法为${empty 变量},结果为布尔值。

  • 若变量未定义,则返回值为 true
  • 若变量为 String 类型,且其值为空串,则返回值为 true。
  • 若变量为引用类型,且其值为 null,则返回值为 true。
  • 若变量为集合类型,且其不包含任何元素,则返回值为 true。

 

下面重点讲一下这个 empty :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,test.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<!--  Empty: -->
<%
    request.setAttribute("empty_0", "");
    request.setAttribute("empty_1", null);
    request.setAttribute("empty_2", new ArrayList());
%>

${ empty undefined }
${ empty  empty_0}
${empty  empty_1}
${empty  empty_2}

<%-- true true true true  --%>

</body>
</html>

 

 

就那么多 ,带脑子看啊!  记住你设置的 那个 key 别和 EL表达式的运算符一样!

  






 


作者:​​咸瑜​​​


本文摘自 :https://blog.51cto.com/u


更多科技新闻 ......