(20):JSP 表达式语言(EL表达式)

(20):JSP 表达式语言(EL表达式)

前言

JSP 表达式语言(Expression Language),也就是EL表达式 。

学习EL 表达式,可以让我们JSP写起来更加简单,让JSP代码更加简化。EL 表达式比较重要,不过非常简单 " ${} " 。

EL 表达式最主要的作用就是在jsp中获取与显示作用域中的数据。

一、EL 表达式

1.概念

EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。

以MVC模式设计程序,JSP只是视图,视图的任务就是显示响应,而不是在JSP中做任何关于程序控制和业务逻辑的事情。所以在JSP页面中应该尽可能少的、或者是完全不出现Java代码。

在MVC实际模式中,JSP作为视图层,用于显示响应。

EL 表达式最主要的作用就是在jsp中获取与显示作用域中的数据。

2.语法

在JSP中访问模型对象是通过EL表达式的语法来表达。所有EL表达式的格式都是以“${}”表示。例如,$代表获取变量userinfo的值。当EL表达式中的变量不给定范围时,则默认在page范围查找,然后依次在request、session、application范围查找。也可以用范围作为前缀表示属于哪个范围的变量,例如:$表示访问page范围中的userinfo变量。

EL 表达式的语法为:$

3.存取数据

EL 提供“.“和“[ ]“两种运算符来存取数据。
当要存取的属性名称中包含一些特殊字符,如 . 或 - 等并非字母或数字的符号,就一定要使用“[ ]“。例如:
$
应当改为${user["My-Name"]}
如果要动态取值时,就可以用“[ ]“来做,而“.“无法做到动态取值。例如:
${sessionScope.user[data]}中data 是一个变量

Java语法也不允许用 "." 或 "-" 作为属性名称。这边的"[]"可以用来取请求头中的信息,或者作为列表或数字的下标,用于获取值。

例如,获取请求头中的"user-agent"信息的EL表达式:${header["user-agent"]}。或者获取list中的第1个数:${list[0]}

4.举例(获取变量)

EL存取变量数据的方法很简单,例如:$。它的意思是取出某一范围中名称为username的变量。
因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找。
假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传""。

例如,你在 Servlet 中写入了这一句 " request.setAttribute("name", "zhangsan") ",将一个为 name 的 key(键)放入了 request 对象中,那么你可以在 JSP 中使用 " $ " 来获取到存入request对象中的值。

EL 表达式前面的 requestScope 代表的是 request 作用域,后面的 name 代表键或变量名,其他作用域同理。例如,session(sessionScope)、application(applicationScope)。使用 " $ " 就相当于 JSP 语法中的 " <%=request.getAttribute("name") %> "。

当然你可以不加上前面的requestScope,使用 " $ " 也可以获取到值。不过默认是从 page 作用域范围开始查找。
然后依次是 request ➡ session ➡ application。

需要 JSP 语法,请点击:Java EE基础(18):JSP语法 + JSP指令(3大指令) + JSP动作
需要JSP 内置对象与作用域,请点击:Java EE基础(19):JSP九大内置对象(又称隐式对象) + JSP四大作用域

EL表达式的属性如下:属性范围,就是 JSP 中的四大作用域。具体请看 7.1 作用域隐式对象
| 属性范围 | 属性范围在EL中的名称 |
|:--|:--|
|Page |pageScope (当前页面内的数据) |
| Request |requestScope (当前请求的数据) |
| Session | sessionScope(当前会话的数据) |
| Application | applicationScope(当前项目的数据,也称Web上下文) |

5.文字

JSP 表达式语言定义可在表达式中使用的以下文字:

也就是一些值,字符串,布尔,数字,空。使用 EL 表达式的时候可以使用,比如 "${score + 10}"。和Java一样的。
| 文字 | 文字的值 |
|:--|:--|
| Boolean |true 和 false |
| Integer| 可以包含任何整数,如:1,123,-321 |
| Floating Point| 可以包含任何正的或负的浮点数,例如 -1.8E-45、4.567 |
| String| 任何由单引号或双引号限定的字符串。对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则单引号不需要转义。 |
| Null| null |

6.操作符

JSP 表达式语言提供以下操作符,其中大部分是 Java 中常用的操作符:

EL 表达式中提供的操作符,和大部分都是Java中常用的。

术语定义
算术型+(加)、-(减)、*(乘)、/ 或 div(除)、% 或 mod(取余)、
逻辑型&& 或 and(或)、|| 或 or(与)、! 或 not(非,取反)
关系型> 或 gt(大于)、< 或 lt(小于)、>= 或 ge(大于等于)、<= 或 le(小于等于)、== 或 eq(等于)、!= 或 ne(不等于)
empty (空)
条件型A ?B :C。根据 A 赋值的结果来赋值 B 或 C(就是Java中的三目运算)。

7.隐式对象

7.1 作用域隐式对象

有些对象允许访问多种范围的变量,如 Web 上下文、会话、请求、页面

也就是不同作用域范围的对象。同上4.举例(获取变量)。比较常用的是requestScope 和 sessionScope 。

隐含对象描述
pageScopepageScope 作用域(当前页面内的数据)。将页面范围的变量名称映射到其值。例如,EL 表达式可以使用 $ 访问一个 JSP 中页面范围的对象,还可以使用 $ 访问对象的属性。
requestScoperequestScope 作用域(当前请求的数据)。 将请求范围的变量名称映射到其值。该对象允许访问请求对象的属性。例如,EL 表达式可以使用 $ 访问一个 JSP 请求范围的对象,还可以使用 $ 访问对象的属性。
sessionScopesessionScope 作用域(当前会话的数据)。将会话范围的变量名称映射到其值。该对象允许访问会话对象的属性。例如:$
applicationScopeapplicationScope 作用域(当前项目的数据,也称Web上下文)。 将应用程序范围的变量名称映射到其值。该隐式对象允许访问应用程序范围的对象。
7.2 其他隐式对象

JSP 表达式提供几个隐式对象,允许对以下对象进行简易访问

下面几个隐式对象不是很常用,了解一下。
|隐含对象 | 描述 |
|:--|:--|
| param | 将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 ${param . name}相当于 request.getParameter (name)。 |
| paramValues| 将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 $
相当于 request.getParamterValues(name)。 |
| header| 将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 $
相当于 request.getHeader(name)。 |
| headerValues| 将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 $
相当于 request.getHeaderValues(name)。 |
| cookie| 将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 $
返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 $ 表达式。 |
| initParam| 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 |

二、示例

1.简单使用

创建一个Servlet和jsp,在Servlet中的request对象中添加一个属性 "name",并且给定值 "zhangsan"。同时请求转发到first.jsp页面。在jsp页面中使用 EL 表达式获取数据。

我这里使用的还是这篇博客中的案例:Java EE基础(16):JSP概念 + 简单使用 + 运行原理
在这里插入图片描述
获取数据:
在这里插入图片描述
效果:
在这里插入图片描述

2.使用操作符 + 隐式对象

还是使用上面的first.jsp页面,只不过修改一下 EL 表达式。

只截图了一部分代码,具体请查看下面的源码。
在这里插入图片描述
在这里插入图片描述

3.源码

Java 代码

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/A")
public class A extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("name", "zhangsan");
		request.setAttribute("score", 100);
		
		// 附加,在jsp中使用"[]"获取list中数据
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(2);
		list.add(3);
		request.setAttribute("list", list);
		request.getRequestDispatcher("/first.jsp").forward(request, response);
	}
	
}

JSP代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" isErrorPage="true" errorPage="error.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>使用操作符</h1>
	<h3>算数型:</h3>
	${score + 2681351684135451} &emsp; 
	${score - 2}    &emsp; 
	${score * 2}    &emsp; 
	${score / 2}    &emsp; 
	${score div 2}  &emsp; 
	${score % 2}    &emsp; 
	${score mod 2}  &emsp; 
	<h3>逻辑型:</h3>
	${score == 100 && 1 == 1}   &emsp; 
	${score == 100 and 1 == 1}  &emsp; 
	${score == 100 || 1 == 1}   &emsp; 
	${score == 100 or 1 == 1}   &emsp; 
	${!false}     &emsp; 
	${not false}  &emsp; 
	<h3>关系型:</h3>
	${score > 100}   &emsp; 
	${score gt 100}  &emsp; 
	${score < 100}   &emsp; 
	${score lt 100}  &emsp; 
	${score >= 100}  &emsp; 
	${score ge 100}  &emsp; 
	${score <= 100}  &emsp; 
	${score le 100}  &emsp; 
	${score == 100}  &emsp; 
	${score eq 100}  &emsp; 
	<h3>空型:</h3>
	${score == null}  &emsp; 
	${empty score}    &emsp; 
	<h3>条件型:</h3>
	${score == 100 ? 101 : 99}  &emsp; 
	<hr>

	<h1>使用隐式对象</h1>
	
	<h3>作用域隐式对象:</h3>
	在requestScope作用域中,我们可以看到我们添加的name和score: <br>
	${requestScope } <hr>
	什么都没添加的sessionScope作用域: <br>
	${sessionScope } <hr>
	
	<h3>其他隐式对象:</h3>
	请求头信息:<br>
	${header }<hr>
	获取请求头中的user-agent:<br>
	${header["user-agent"] }	

	<h1>附加</h1>
	${list } <br>
	使用"[]"获取list中数据:<br>
	${list[0] } <br>
	${list[1] } <br>
	${list[2] } <br>	
</body>
</html>

其他的隐式对象也是如此,如果想看可以在jsp中加上EL表达式查看。

其他

参考

EL 表达式:https://baike.baidu.com/item/EL%E8%A1%A8%E8%BE%BE%E5%BC%8F/1190845

JSP 表达式语言:https://www.runoob.com/jsp/jsp-expression-language.html