EL(表达式语言)

EL(表达式语言)

制作人:全心全意

EL的基本语法

EL表达式语法很简单,它以“${”开头,以“}”结束,中间为合法的表达式,具体的语法格式如下:

  ${expression}

  参数说明:

    expression:用于指定要输出的内容,可以是字符串,也可以是由EL运算符组成的表达式。

技巧:用于EL表达式的语法以“${”开头,所以如果在JSP网页中要显示“${”字符串,必须在前面加上“\”符号,即“\${”,或者写成“${'${'}”,也就是用表达式来输出“${”符号。

 

 

EL的特点

  • EL可以与JSTL结合使用,也可以与JavaScript语句结合使用。
  • EL中会自动进行类型转换。如果想通过EL输出两个字符串型数值(例如,number1和number2)的和,可以直接通过+号进行连接(例如:${number1+number2})。
  • EL不仅可以访问一般变量,而且还可以访问JavaBean中的属性以及嵌套属性和集合对象。
  • 在EL中可以执行算术运算、逻辑运算、关系运算和条件运算等。
  • 在EL中可以获得命名空间(PageConext对象,它是页面中所有其他内置对象的最大范围的集成对象,通过它可以访问其他内置对象)。
  • 在使用EL进行除法运算时,如果0作为除数,则返回无穷大infinity,而不返回错误。
  • 在EL中可以访问JSP的作用域(request、session、application以及page)。
  • 扩展函数可以与Java类的静态方法进行映射。

 

禁用EL

 如今EL已经是一项成熟、标准的技术,只要安装的Web服务器能够支持Servlet2.4/JSP 2.0,就可以在JSP页面中直接使用EL。由于在JSP2.0以前的版本中没有EL,所以JSP为了和以前的规范兼容,还提供了禁用EL的方法。JSP提供了以下3种禁用EL的方法,下面将分别进行介绍。

使用斜杠“\”符号

 使用斜杠符号是一种比较简单的禁用EL的方法。该方法只需要在EL的起始标记“${”前加上“\”符号,具体的语法如下:

\${expression}

  

使用page指令

 使用JSP的page指令也可以禁用EL表达式,其具体的语法格式如下:

<%@ page isELIgnored="布尔值" %>

 isELIgnored属性:用于指定是否禁用页面中的EL,如果属性值为true,则忽略页面中的EL,否则将解析页面中的EL。

 

在web.xml文件中配置<el-ignored>元素

 在web.xml文件中配置<el-ignored>元素可以实现禁用服务器中的EL。

 在web.xml文件中配置<el-ignored>元素的具体代码如下:

	<jsp-config>
		<jsp-property-group>
			<url-pattern>*.jsp</url-pattern>
			<el-ignored>true</el-ignored>
			<!-- 将此处的值设置为false,表示使用EL -->
		</jsp-property-group>
	</jsp-config>

 

EL保留的关键字

同java一样,EL也有自己的保留关键字,在为变量命名时,应该避免使用这些关键字,包括在使用EL输出已经保存在作用域范围内的变量也不能使用关键字,如果已经定义了,那么需要修改为其它的变量名。EL的保留关键字如下表所示。

and eq gt
instanceof div or
le false empty
not lt ge

 

EL的运算符及优先级

运算符的优先级决定了在多个运算符同时存在时,各个运算符的求值顺序,对于同级运算符采用从左向右计算的原则。使用括号()可以改变优先级。运算符的优先级如下图所示。

 

 

通过EL访问数据

通过EL提供的“[]”和“.”运算符可以访问数据。通常情况下,“[]”和“.”运算符是等价的,可以相互代替。

例如:访问JavaBean对象userInfo的id属性,可以写成以下两种形式:

${userInfo.id}
${userInfo[id]}

注意:不是所有情况下都可以相互替代,当对象的属性名中包括一些特殊的符号(-获.)时,就只能使用“[]”运算符来访问对象的属性。另外,EL的“[]”还有一个用途,就是用来获取数组或者List集合中的数据。

例:List集合元素的获取(向session域中保存一个包含3个元素的List集合对象,并应用EL输出该集合的全部元素)

<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>首页</title>
</head>
<body>
	<%
		List<String> list = new ArrayList<String>();
		list.add("香蕉");
		list.add("苹果");
		list.add("大鸭梨");
		session.setAttribute("goodsList", list);
	%>
	<%
		List<String> list1 = (List<String>) session.getAttribute("goodsList");
		for (int i = 0; i < list.size(); i++) {
			request.setAttribute("requestI", i);
	%>
	${requestI} : ${goodsList[requestI]}
	<!-- 应用“[]”运算符可以获取List集合中的指定元素,但是“.”运算符则不能 -->
	<br>
	<%
		}
	%>
</body>
</html>

注意:在上面的代码中,必须将循环变量i保存到request范围内的变量中,否则将不能正确访问数组,这里不能直接使用Java代码片段中定义的变量i,也不能使用<%=i%>输出i。

 

通过EL进行算术运算

在EL中,也可以进行算术运算,同Java语言一样,EL提供了加、减、乘、除和求余5种算术运算符,各运算符及其用法,如下表所示。

运   算   符 功     能 示     例 结     果
+ ${19+1} 20
- ${66-30} 36
* ${52.1*10} 521.0
/ 或 div ${5/2}或${5 div 2} 2.5
${9/0}或${9 div 0} Infinity
% 或 mod 求余 ${17%3}或${17 mod 3} 2
${15%0}或${15 mod 0} 抛出异常:java.lang.ArithmeticException:/by zero

 

通过EL判断对象是否为空

在EL中,判断对象是否为空,可以通过empty运算符实现,该运算符是一个前缀(prefix)运算符,即empty运算符位于操作数前方,用来确定一个对象或变量是否为空或null。empty运算符的格式如下:

${empty expression}<!--判断对象是否为空-->
${not empty expression}<!--判断对象是否非空-->

参数说明如下:

expression:用于指定要判断的变量或对象。

 

通过EL进行逻辑关系运算

在EL中,通过逻辑运算符和关系运算符可以实现逻辑关系运算。关系运算符用于实现对两个表达式的比较,进行比较的表达式可以是数值型,也可以是字符串型。而逻辑运算符,则常用于对boolean型数据进行操作。逻辑运算符和关系运算符经常一同使用。逻辑关系运算语法如下:

${表达式1 逻辑关系运算符 表达式2}
  • 关系运算符
运   算   符 功     能 示     例 结     果
== 或 eq 等于     ${10 == 10} true
    ${"A" eq "a"} false
!= 或 ne 不等于     ${10 ne 10} false
    ${"A" != "A"} false
< 或 lt 小于     ${7 < 6} false
    ${"A" lt "B"} true
> 或 gt 大于     ${7 > 6} true
    ${"A" gt "B"} false
<= 或 le 小于等于     ${7 le 6} false
    ${"A" <= "A"} true
>= 或 ge 大于等于     ${7 ge 6} true
    ${"A" >= "B"} false

 

  • 逻辑运算符
运   算   符 功     能 示     例 结     果
&& 或 and     ${true && false} false
    ${true && true} true
|| 或 or     ${true or false} true
    ${false || false} false
! 或 not     ${! true} false
    ${not false} true

 

通过EL进行条件运算

在EL中进行简单的条件运算,可以通过条件运算符实现。EL的条件运算符唯一的优点在于其非常简单和方便,和Java语言里的用法完全一致。其语法格式如下:

${条件表达式 ? 表达式1:表达式2}

参数说明如下:

条件表达式:用于指定一个条件表达式,该表达式的值为boolean型。可以由关系运算符、逻辑运算符和empty运算符组成。

表达式1:用于指定当条件表达式的值为true时,将要返回的值。

表达式2:用于指定当条件表达式的值为false时,将要返回的值。

说明:通常情况下,条件运算符可以用JSTL中的条件标签<c:if>或<c:choose>替代

 

 

EL的隐含对象

EL提供了11个隐含对象,这些对象类似于JSP的内置对象,也是直接通过对象名进行操作。

在EL的隐含对象中,除了PageContext是JavaBean对象,对应于javax.servlet.jsp.PageContext类型外,其他的隐含对象都对应于java.util.Map类型。这些隐含对象可以分为页面上下文对象、访问作用域范围和访问环境信息的隐含对象3种。

页面上下文对象

页面上下文对象为pageContext,用于访问JSP内置对象(如request、response、out、session、exception、和page等,但不能用于获取application、config和pageContext对象)和servletContext。在获取到这些内置对象后,就可以获取其属性值。这些属性与对象的getXXX()方法相对应,在使用时,去掉方法名中的get,并将首字母改为小写即可。

例1:通过request对象访问getServerPort()方法

${pageContext.request.serverPort}

注意:不可以通过pageContext对象获取保存到request范围内的变量。

例2:通过exception对象获取异常信息字符串

${pageContext.exception.message}

说明:在使用该对象时,也需要在可能出现错误的页面中指定错误处理页,并且在错误处理页中指定page指令的isErrorPage属性值为true,然后再使用上面的EL输出异常信息。

例3:通过servletContext对象获取servlet上下文路径

${pageContext.servletContext.contextPath}

 

访问作用域范围的隐含对象

在EL中提供了4个用于访问作用域范围的隐含对象,即pageScope、requestScope、sessionScope和applicationScope。应用这4个隐含对象指定所要查找的标识符的作用域后,系统将不再按照默认的顺序(page、request、session及application)来查找相应的标识符。它们与JSP中的page、request、session、及application内置对象类似,只不过这4个隐含对象只能用来取得指定范围内的属性值,而不能取得其他相关信息。

  • pageScope隐含对象:pageScope隐含对象用于返回包含page(页面)范围内的属性值集合,返回值为java.util.Map对象。
  • requestScope隐含对象:requestScope隐含对象用于返回包含request(请求)范围内的属性值集合,返回值为java.util.Map对象。
  • sessionScope隐含对象:sessionScope隐含对象用于返回包含session(会话)范围内的属性值的集合,返回值为java.util.Map对象。
  • applicationScope隐含对象:applicationScope隐含对象用于返回包含application(应用)范围内的属性值的集合,返回值为java.util.Map对象。

例:通过pageScope隐含对象用于返回包含page范围内的JavaBean的属性值

UserInfo类:用户名的JavaBean

package com.zq;

public class UserInfo {
	private String name = "";  //用户名

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

index.jsp页面:应用pageScope隐含对象获取该JavaBean实例的name属性

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>pageContext</title>
</head>
<body>
	<!-- 应用pageScope隐含对象获取该JavaBean实例的name属性 -->
	<jsp:useBean id="user" scope="page" class="com.zq.UserInfo"
		type="com.zq.UserInfo">
		<jsp:setProperty property="name" name="user" value="全心全意" /></jsp:useBean>
	${ pageScope.user.name }
	<br>
	<!-- 应用requestScope隐含对象获取request范围内的userName变量 -->
	<%
		request.setAttribute("userName", "quanxinquanyi");
	%>
	${requestScope.userName }
</body>
</html>

 

访问环境信息的隐含对象

  • param对象:param对象用于获取请求参数的值,应用在参数值只有一个的情况。在应用param对象时,返回的结果为字符串。(例如表单)

例:param对象的使用示例(表单)

放置一个名称为user的文本框

<input name="name" type="text" />

在表单提交页面,获取name文本框的值

${param.name}

注意:如果使用中文,需应用“request.setCharacterEncoding("字符编码")”设置支持中文的字符编码。

 

  • paramValues对象:如果一个请求参数对应多个值时,则需要使用paramValues对象获取请求参数的值。在应用paramValues对象时,返回的结果为数组。(例如复选框)

 

  • header和headerValues对象:header对象用于获取HTTP请求的一个具体的header的值,但是在有些情况下,可能存在同一个header拥有多个不同的值的情况,这时就必须使用headerValues对象。

 

  • initParam对象:initParam对象用于获取Web应用初始化参数的值(初始化参数为web.xml文件中定义的初始化参数)

 

  • cookie对象:虽然在EL中,并没有提供向cookie中保存值的方法,但是它提供了访问由请求设置的cookie的方法,这可以通过cookie隐含对象实现。如果在cookie中已经设定一个名称为username的值,那么可以使用${cookie.username}来获取该cookie对象。但是如果要获取cookie中的值,需要使用cookie对象的value属性${cookie.username.value}。

例:cookie对象的使用示例

使用response对象设置一个请求有效的cookie对象,然后再使用EL获取该cookie对象的值

<%
    Cookie cookie = new Cookie("user","quanxinquanyi");
    response.addCookie(cookie);
%>
${cookie.user.value}

 

 注意:在应用param和paramValues对象时,如果指定的参数不存在,则返回空的字符串,而不是返回null。

 

 

定义和使用EL函数

EL函数的定义和使用分为以下3个步骤:

(1)编写一个Java类,并在该类中编写公用的静态方法,用于实现自定义EL函数的具体功能。

(2)编写标签库描述文件,对函数进行声明。该文件的扩展名为.tld,被保存到Web应用的WEB-INF文件夹下。

(3)在JSP页面中引用标签库,并调用定义的EL函数,实现相应的功能

例:定义EL函数处理字符串中的回车换行符和空格符。

StringDeal类:添加一个公用的静态的方法shiftEnter(),在该方法中替换输入字符串中的回车换行符为<br>,空格符为&nbsp;,最后返回新替换后的字符串。

package com.zq;

public class StringDeal {
	public static String shiftEnter(String str) {
		String newStr = str.replaceAll("\r\n", "<br>"); // 替换回车换行符
		newStr = newStr.replaceAll(" ", " ");// 替换空格符
		return newStr;
	}
}

 

stringDeal.tld文件:标签库的描述文件,将其保存到WEB-INF文件夹下。

<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	web-jsptaglibrary_2_0.xsd"
	version="2.0">
	<tlib-version>1.0</tlib-version>
	<uri>/stringDeal</uri>
	<!-- 指定tld文件的映射路径。在应用EL函数时,需要使用该标记指定的内容 -->
	<function>
		<name>shiftEnter</name>
		<!-- 对应EL函数对应的方法名,通常与Java文件中的方法名相同 -->
		<function-class>com.zq.StringDeal</function-class>
		<!-- 对应静态类,这里需要包括包名和类名 -->
		<function-signature>java.lang.String shiftEnter(java.lang.String)
		</function-signature>
		<!-- 对应静态方法,这里包括返回值的类型和入口参数的类型 -->
	</function>
</taglib>

 

index.jsp页面:放置一个表单及表单元素,用于收集内容信息。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>welcome</title>
</head>
<body>
	<form name="form1" method="post" action="deal.jsp">
		<textarea name="content" cols="30" rows="5"></textarea>
		<br> <input type="submit" name="Button" value="提交">
	</form>
</body>
</html>

 

deal.jsp页面:对获取到的内容信息进行处理后显示到页面中。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="/stringDeal" prefix="wghfn"%>
<!-- 引用标签库时,指定的uri属性与标签库描述文件中的<uri>标记的值是相对应的 -->
<%
	request.setCharacterEncoding("utf-8");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>显示结果</title>
</head>
<body>
	内容为:
	<br> ${wghfn:shiftEnter(param.content) }
</body>
</html>

  

定义和使用EL函数时常见错误

  • 由于没有指定完整的类型名而产生异常信息
  • 由于在标签库的描述文件中输入了错误的标记名产生的异常信息
  • 由于定义的方法不是静态方法所产生的异常信息

 

posted @ 2018-11-12 13:58  全心全意_运维  阅读(1440)  评论(0编辑  收藏  举报