5. JSP - 表达式语言 - EL

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表达式的运算符一样!

  
























 

posted @ 2021-05-30 18:28  咸瑜  阅读(186)  评论(0编辑  收藏  举报