likes
comments
collection
share

深入了解EL表达式

作者站长头像
站长
· 阅读数 19

EL表达式

1、EL概述

1.1 引入

问题:

按照前面文章中提到的代码实现方式,如果用户登录失败,我们不用再单独书写一个LoginErrorServlet,直接新创键一个login.jsp页面即可。

但是我们先访问login.html,然后错误在跳转到login.jsp页面,那么我们是否可以直接访问login.jsp页面,而不用再使用login.html页面。这样更为简单。

在浏览器中直接访问login.jsp页面:

深入了解EL表达式

我们发现最开始访问jsp页面,页面显示null,原因是最开始访问request中的msg没有任何数据,所以是null。那么有的同学就会想在login.jsp页面中使用java代码对request中的msg进行判断。虽然可以实现,但是脚本表达式在JSP页面上书写起来比较麻烦。而在页面上取值在开发中使用的又比较多,所以Sun公司为了简化在页面上的取值操作。我们这里有更为简单的方案,就是我们下面要讲解的EL表达式。

【需求】使用EL表达式改造login.jsp页面的取值操作

提示:EL表达式从request域对象中取值:${request域对象中的key}

温馨提示:

原来JSP页面中的脚本表达式<%=msg%>被EL表达式取代。

【代码示例】login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>登录页面</title>

    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/login.css" rel="stylesheet">
    <script src="js/jquery.js"></script>
    <script src="js/bootstrap.js"></script>
</head>
<body>
<%
//    String msg = (String) request.getAttribute("msg");
%>
<div class="container text-center">
    <form class="form-signin" action="/loginInterServlet" method="get">
        <h2 class="form-signin-heading">登录页面</h2>
        <%--<font color="red"><%=msg%></font>--%>
        <font color="red">${msg}</font>
        <input type="text"  name="username" class="form-control" placeholder="用户名" required autofocus>
        <input type="password"  name="password" class="form-control" placeholder="密码" required>
        <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
    </form>
</div>

</body>
</html>

说明:

1)在jsp页面中使用EL表达式可以简化Java代码。

2)EL表达式从域对象取值,如果域对象中有值则获取,没有值则不获取。

1.2 EL简介

EL全称: Expression Language 中文的意思是EL表达式。
作用:代替jsp中脚本表达式<%=输出内容%>的功能,简化对java代码的操作,从【域对象】中取值。 EL表达式简化<%= %>方式取值   
EL语法表达式的格式:${域对象中的key} 

2、EL取值

2.1 JSP的四大域对象

JSP的四大域对象指的是:page域,request域,session域,application域。我们通常使用EL表达式从这4个域对象中取值。以下是这4个域对象的详细信息:

域对象在EL中的对象名称在servlet中的对象名说明
page域pageScopepageContext,属于javax.servlet.jsp.PageContext类的对象page域指的是当前JSP页面,其中存储的数据只在当前页面有效,因为jsp本质是servlet,所以page域只在一个servlet中有效。
request域requestScoperequest,属于javax.servlet.http.HttpServletRequest接口的对象request域:一次请求或请求链中request域
session域sessionScopesession,属于javax.servlet.http.HttpSession接口的对象session域:一次会话过程中,session域
application域applicationScopeapplication,属于javax.servlet.ServletContext接口的对象application域:服务启动后整个项目对应的ServletContext域

2.2 EL表达式从四大域中取值

EL表达式从指定的域中取值的方式如下:

域对象取值方式
page域${pageScope.key}
request域${requestScope.key}
session域${sessionScope.key}
application域${applicationScope.key}

【需求】

  1. 在一个JSP页面中,使用脚本片段分别向page域、request域,session域,application域和中存储数据;
  2. 使用EL表达式从这4个域中取值;

【参考代码】

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--
             EL表达式 page  request  session  application 四大域对象
             【需求】
            1. 在一个JSP页面中,使用脚本表达式分别向page域、request域,session域,application域和中存储数据;
            2. 使用EL表达式从这4个域中取值;
    --%>
    <%
        //page域,对一servlet中的pageContext对象
        pageContext.setAttribute("pageValue","page的值");
        //request域
        request.setAttribute("requestValue","request的值");
        //session域
        request.getSession().setAttribute("sessionValue","session的值");
        //application域,属于ServletContext类的对象
        application.setAttribute("applicationValue","application的值");
    %>
    <%--
        EL表达式来域对象中取值
    --%>
    page中取值:${pageScope.pageValue}<br>
    request中取值:${requestScope.requestValue}<br>
    session中取值${sessionScope.sessionValue}<br>
    application中取值${applicationScope.applicationValue}<br>
</body>
</html>

深入了解EL表达式

2.3 EL表达式搜索数据

EL表达式取值的时候也可以不指定域,如果取值的时候不指定域对象。就会按照从page域--->request域--->session域--->application域从小到大逐级根据key值查找。


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--
             EL表达式 page  request  session  application 四大域对象
             【需求】
            1. 在一个JSP页面中,使用脚本表达式分别向page域、request域,session域,application域和中存储数据;
            2. 使用EL表达式从这4个域中取值;
    --%>
    <%
        //page域,对一servlet中的pageContext对象
        pageContext.setAttribute("pageValue","page的值");
        //request域
        request.setAttribute("requestValue","request的值");
        //session域
        request.getSession().setAttribute("sessionValue","session的值");
        //application域,属于ServletContext类的对象
        application.setAttribute("applicationValue","application的值");
        //向域对象中存储值,key值一样,则先从小向大的域中查找
        pageContext.setAttribute("value","page的值");
        request.setAttribute("value","requst的值");
    %>
    <%--
        EL表达式来域对象中取值
    --%>
    page中取值:${pageScope.pageValue}<br>
    request中取值:${requestScope.requestValue}<br>
    session中取值${sessionScope.sessionValue}<br>
    application中取值${applicationScope.applicationValue}<br>
    相同的key:${value}
</body>
</html>

深入了解EL表达式

2.4 EL表达式从cookie中取值

之前我们在学习cookie的时候,做过记住用户名和密码的案例,但是前端页面我们并没有实现。因为我们还没有学习使用什么技术在前端如何将cookie中的数据取出,而今天我们学习了EL表达式,我们就可以实现前端记住用户名和密码的案例了。

new Cookie(name,value)

使用EL表达式获取cookie中的值格式:(掌握)

cookie.cookie的name名.value
例如:
 Cookie cookieName = new Cookie("username","锁哥");
 cookie.username.value获取的值是锁哥。

创建一个登陆的jsp页面:

<%--
  Created by IntelliJ IDEA.
  Time: 16:52
  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>
    <form action="/login2Servlet">
        <input name="username" type="text" placeholder="请输入账号"><br>
        <input name="password" type="password" placeholder="请输入密码"><br>
        <input type="submit" value="登录">
        <br>
        <input type="checkbox" name="ck" class="checkbox">记住用户名和密码
    </form>
</body>
</html>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <form action="/loginServlet" method="post">
        <%--
            ${cookie.username.value} 表示从浏览器存储的cookie中获取值
            cookie表示对象名
            username 表示cookie中的名,看服务器端给的什么名字,这里就写什么名字,不固定。可以理解为key
            value属于固定属性。表示获取值
        --%>
        用户名:<input type="text" name="username" value="${cookie.username.value}"><br>
        密码:<input type="password" name="password" value="${cookie.password.value}"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

在servlet生成cookie LoginServlet.java

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //创建cookie
        Cookie cookieName = new Cookie("username",username);
        Cookie cookiePsw = new Cookie("password",password);
        response.addCookie(cookieName);
        response.addCookie(cookiePsw);
    }
}

温馨提示:要去访问Java代码LoginServlet,才能将cookie存储到浏览器中

效果图:

先访问:http://localhost:8080/login.jsp也面,点击登录按钮,访问了LoginServlet,在LoginServlet中 生成cookie。

再访问login.jsp页面,使用EL表达式获取用户名和密码

http://localhost:8080/login.jsp

深入了解EL表达式

3、EL运算符

EL表达式获取到值之后可以直接通过运算符进行运算。EL表达式的运算符主要有以下几类:算术运算,关系运算,逻辑运算,三元运算,empty运算符。

【素材】页面数据准备demo08.jsp

<%
    request.setAttribute("n1",40);
    request.setAttribute("n2",30);
    request.setAttribute("n3","20");
    request.setAttribute("n4","10");
%>

3.1 算术运算

顾名思义,算术运算是进行算术运算的符号,和java中的一致。主要包括:加,减,乘,除,取余。具体使用如下表:

运算符说明使用示例结果
+${n1+n2}70
-${n1-n2}10
*${n1*n2}1200
/或div${n1/n4}4
%或mod取余${n1%n4}0

【代码示例】demo08.jsp代码片段

算数运算:<br>
    n1+n2:${n1 + n2}<br>
    n1-n3:${n1 - n3}<br>
    n3-n4:${n3-n4}<br>
    n2*n3:${n2 * n3}<br>

效果图:

深入了解EL表达式

注意:在进行算术运算的时候,EL表达式会对字符串中的内容进行判断,如果都是数值,那么会转化为数值再进行算术运算,如果含有非数字类型,则会报异常。

3.2 关系运算

<%
    request.setAttribute("n1",40);
    request.setAttribute("n2",30);
    request.setAttribute("n3","20");
    request.setAttribute("n4","10");
%>

关系运算符是判断两个数据的大小关系的,关系运算符有:==,!=,<,<=,>,>=。具体使用方法如下:

运算符说明使用示例结果
== 或 eq等于 equal${n1 == n2}false
!= 或ne不等于 not equal${n1 != n2}true
> 或 gt大于 greater than${n1 > n2}true
>= 或ge大于等于 greater than or equal${n1 >= n2}true
< 或 lt小于 less than${n1 < n2}false
<= 或le小于等于 less than or equal${n1 <= n2}false

【代码示例】demo08.jsp

关系运算符:<br>
n1==n2:${n1==n2}<br>
n3>=n4:${n3>=n4}<br>
n1!=n2:${n1 ne n2}<br>

效果:

深入了解EL表达式

3.3 逻辑运算

逻辑运算符包括:&& ,||,! 使用方法如下:

运算符说明使用示例结果
&& 或 and逻辑与,一假即假${true && false}false
或 or逻辑或,一真即真`${truefalse}`true
! 或 not非,取反${!false}true

参考代码demo08.jsp

逻辑运算符:<br>
false && true:${false && true}<br>
false || true:${false || true}<br>
!false:${!false}<br>

3.4 三元运算

EL表达式也支持三元运算符:如,判断n1是否大于等于n2,可以写成如下:参考代码demo08.jsp

<%--
    表达式1?表达式2:表达式3
--%>
三元运算符:<br>
${n1>=n2?"正确":"错误!"}<br>

3.5 empty运算

empty运算符表示判断数据是否为空,如果为空返回true。对以下数据运算返回true:

  1. 字符串:"";
  2. 空集合(size=0):List list = new ArrayList();
  3. 空对象(null):Student stu = null;String s=null;Object obj=null;

【代码示例】 demo08.jsp

<%
        String str = "";
        request.setAttribute("str",str);
        Student student=null;
        request.setAttribute("student",student);
        List<String> list = new ArrayList<>();
        request.setAttribute("list",list);
 %>
    empty:<br>
    ${empty str}<br>
    ${empty student}<br>
    <%--
        not empty list :表示对empty的结果取反,由于list.size()等于0,所以empty list的结果是true,
        但是这里加了一个not,结果变为了false
    --%>
    ${not empty list}<br>

页面效果:

深入了解EL表达式

demo08.jsp完整代码

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.ithea.sh.el.cookie_01.Student" %><%--
  Created by IntelliJ IDEA.
  Time: 8:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>运算符</title>
</head>
<body>
    <%
        //向request域对象中存储数据
        request.setAttribute("n1",40);
        request.setAttribute("n2",30);
        request.setAttribute("n3","20");
        request.setAttribute("n4","10");
    %>
    算数运算:<br>
    n1+n2:${n1 + n2}<br>
    n1-n3:${n1 - n3}<br>
    n3-n4:${n3-n4}<br>
    n2*n3:${n2 * n3}<br>
    关系运算符:<br>
    n1==n2:${n1==n2}<br>
    n3>=n4:${n3>=n4}<br>
    n1!=n2:${n1 ne n2}<br>
    逻辑运算符:<br>
    false && true:${false && true}<br>
    false || true:${false || true}<br>
    !false:${!false}<br>
    <%--
     表达式1?表达式2:表达式3
    --%>
    三元运算符:<br>
    ${n1>=n2?"正确":"错误!"}<br>
    <%
        String str = "";
        Student student=null;
        List<String> list = new ArrayList<>();
    %>
    empty:<br>
    ${empty str}<br>
    ${empty student}<br>
    <%--
        not empty list :表示对empty的结果取反,由于list.size()等于0,所以empty list的结果是true,
        但是这里加了一个not,结果变为了false
    --%>
    ${not empty list}<br>
</body>
</html>

效果图:

深入了解EL表达式

【注】not empty可以用在EL表达式中,判断非空的情况。

EL表达式小结:

  • EL:Expression Language;

  • EL语法:${ }

  • 作用:简化脚本表达式的取值,简化<%= request.getAttribute("name") %> ===> ${name}

  • jsp的四大域对象

    • page域:pageContext pageContext.setAttrubute() pageContext.getAttribute() JSP特有 作用范围:当前的JSP页面
    • requst域:request request.setAttribute() request.getAttribute() 作用范围:一次请求和响应之间
    • session域: session session.setAttribute() session.getAttribute() 作用范围:会话期间(多次请求和响应)
    • servletContext域:application application.setAttribute() application.getAttribute() 作用范围:整个项目;
  • jsp从四大域中取值(指定域对象):

    • ${pageScope.name}
    • ${requestScope.name}
    • ${sessionScope.name}
    • ${applicationScope.name}
  • JSP搜索域对象中的值:page --- request --- session --- servletContext

    • ${name}
  • 运算

    • 算术运算

    • 关系运算

    • 逻辑运算:&& || !

    • 三元运算

    • empty运算:empty not empty

      • 空字符串:""
      • 空对象:null
      • 空集合:list.size = 0;