表达式语言(Expression Language)简称EL,它是JSP2.0中引入的一个新内容。通过EL可以简化在JSP开发中对对象的引用,从而规范页面代码,增加程序的可读性及可维护性。EL为不熟悉Java语言页面开发的人员提供了一个开发Java Web应用的新途径。下面对EL的语法、运算符及隐含对象进行简单介绍(EL就不详解介绍了,这里主要介绍一些常用的,有需要的自己了解一下)。
EL简介
EL没出现之前,开发Java Web应用程序时,经常需要将大量的Java代码片段嵌入到JSP页面中,这会使页面开起来很乱,如下例子:
<%if(session.getAttribute(“username”)!= null){
out.println(session.getAttribute(“username”).toString());
}%>
经常写这种痛苦的代码杀了我们算了,所以EL应运而生
以上代码只需下面的简单代码即可:
${username}
通过上面的例子我们可以知道,EL表达式的语法非常简单,它以”${”开头,以”}”结束,中间为合法的表达式,具体的语法格式为:
${expression}
expression用于指定要输出的内容,可以使字符串,也可以是由EL运算符组成的表达式。
EL的特点:
- EL表达式不能出现在Java代码块、表达式块等JSP动态代码部分
- EL只能从四大域属性空间中获取数据(pageContext、request、session、application)
- EL不会抛出空指针异常,只会不显示
- EL不会抛出数组越界异常,只会不显示
- EL不具有对字符串进行处理的能力(可以使用JSTL的EL或者自定义EL函数)
- EL中会自动进行类型转换。如果想通过EL输入两个字符串型数值的和,可以直接通过”+”号进行连接,如${num1+num2};
- EL不仅可以访问一般变量,还可以访问JavaBean中的属性以及嵌套属性和集合对象;
- 在EL中可以获得命名空间(PageContext对象,它是页面中所有其他内置对象的最大范围的集成对象,通过它可以访问其他内置对象);
- 在使用EL进行除法运算时,如果除数为0,则返回无穷大Infinity,而不是错误;
- EL可以与JSTL结合使用,也可以与JavaScript语句结合使用;
- 扩展函数可以与Java类的静态方法进行映射。
EL的常用方法
EL的算数运算符
运算符 | 功能 | 示例 | 结果 |
---|---|---|---|
+ | 加 | ${1+1} | 2 |
– | 减 | ${1-1} | 0 |
* | 乘 | ${2*2} | 4 |
/或div | 除 | 2/0或{2 div 0} | Infinity |
%或 mod | 求余 | {3%0}或{3 mod0} | 异常:java.lang.ArithmeticException:/by zero |
EL关系运算符
关系运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
== 或 eq | 等于 | ${5==5}或${5eq5} | true |
!= 或 ne | 不等于 | ${5!=5}或${5ne5} | false |
< 或 lt | 小于 | ${3<5}或${3lt5} | true |
> 或 gt | 大于 | ${3>5}或{3gt5} | false |
<= 或 le | 小于等于 | ${3<=5}或${3le5} | true |
>= 或 ge | 大于等于 | ${3>=5}或${3ge5} | false |
El逻辑运算符
逻辑运算符 | 范例 | 结果 |
---|---|---|
&&或and | 交集${A && B}或${A and B} | true/false |
或or|并集${A ¦ ¦ B}或${A or B}|true/false | ||
!或not | 非${! A }或${not A} | true/false |
Empty 运算符和条件运算符
1、在EL中判断对象是否为空
${empty expression}
2、条件运算符
${ A ? B : C}
EL的11个隐式对象
隐含对象 | 类型 | 说明 |
---|---|---|
PageContext | javax.servlet.ServletContext | 表示此JSP的PageContext |
PageScope | java.util.Map | 取得Page范围的属性名称所对应的值 |
RequestScope | java.util.Map | 取得Request范围的属性名称所对应的值 |
sessionScope | java.util.Map | 取得Session范围的属性名称所对应的值 |
applicationScope | java.util.Map | 取得Application范围的属性名称所对应的值 |
param | java.util.Map | 如同ServletRequest.getParameter(String name)。回传String类型的值 |
paramValues | java.util.Map | 如同ServletRequest.getParameterValues(String name)。回传String[]类型的值 |
header | java.util.Map | 如同ServletRequest.getHeader(String name)。回传String类型的值 |
headerValues | java.util.Map | 如同ServletRequest.getHeaders(String name)。回传String[]类型的值 |
cookie | java.util.Map | 如同HttpServletRequest.getCookies() |
initParam | java.util.Map | 如同ServletContext.getInitParameter(String name)。回传String类型的值 |
EL获取属性
1、普通获取
从四大作用域中直接获取xxxxx属性,会从最小的域查找到最大的域
${xxxxx}
2、从某个域获取属性name
${applicationScope.name }
3、pageContext
在EL中直接${pageContext.request}即可获取request对象,其底层调用的是pageContext.getRequest()方法。同理,也可以通过类似方法获取其他对象
其中最常用的:${pageContext.request.contextPath },代表web应用下的根
4、${param.name }
其底层实际调用request.getParameter()
5、paramValues
${paramValues.hobby[0] }
${paramValues.hobby[1] }
6、initParam
获取初始化参数,其底层调用的是ServletContext.getInitParameter()
7、访问bean属性
${student.name}
student是bean,name是其属性
8、访问数组和List
${students[1].name} students是数组或者List
9、访问Map
${map.name } map是Map,name是键,获取其值
自定义EL函数
因为EL本身不具有处理字符串能力,所以可以自定义EL函数
- 定义函数(新建MyEL.java类)
- 注册:先找到jsp2-example-taglib.tld,将头部以及注册函数复制到自己创建的.tld文件中(.tld放在WEB-INF下)
- 在index.jsp中使用,使用时需要<%@ taglib uri=”http://tomcat.apache.org/jsp2-example-taglib” prefix=”MyEL” %>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.5//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
...
</web-app>
描述符2.4或者更新的版本,isELIgnored默认值为false,而2.3或者 更早的版本isELIgnored默认值为true。就导致了出现EL表达式无效的情况(浪费我很长时间,一直在找我的配置问题)。
解决方法1、: 在jsp page指令中共添加属性isELIgnored=”false”
解决方法2、删除web-app之上的头部代码,然后
在web.xml中年添加以下代码
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
</jsp-property-group>
<taglib>
<taglib-uri>http://testcomp.com/testcomp/core</taglib-uri>
<taglib-location>/WEB-INF/tlds/MyEL.tld</taglib-location>
</taglib>
</jsp-config>
此时将el.jsp中的
<%@ taglib uri="http://testcomp.com/testcomp/core" prefix="MyEL" %>
换为
<%@ taglib uri="http://testcomp.com/testcomp/core" prefix="MyEL" %>
即可,这样写有个好处,就是当tld的路径发生改变的时候只需修改web.xml中的路径,而不必每个用到的jsp文件
定义类和处理函数
注意:方法必须是静态的
/**
*
*/
package el;
/**
* @author Administrator
*
*/
public class MyEL {
// 字符串小写变大写
public static String lowerToUpper(String str) {
return str.toUpperCase();
}
}
定义tld文件
在WEB-INF文件下新建一个tld文件,文件头从tomcat的webapps\examples\WEB-INF\jsp2目录的jsp2-example-taglib.tld文件中考过来
如下:
<?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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>这是我自定义的EL</description>
<tlib-version>1.0</tlib-version>
<short-name>MyEL</short-name><!-- 标签库名称,一般定义成和文件名一样 -->
<!-- <uri>http://tomcat.apache.org/jsp2-example-taglib</uri> -->
<!-- 注册函数 -->
<function>
<name>MyLowerToUpper</name>
<function-class>el.MyEL</function-class><!-- 方法的类 -->
<function-signature>java.lang.String lowerToUpper(java.lang.String )</function-signature>
</function>
</taglib>
在el.jsp文件中通过taglib指令引入
<%@ page language="java" import="java.util.*" isELIgnored="false" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib uri="/WEB-INF/tlds/MyEL.tld" prefix="MyEL" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>EL表达式测试页面</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<%
String name="xlj";
pageContext.setAttribute("name", name);
%>
<body>
${MyEL:MyLowerToUpper(name)} <br>
</body>
</html>
其中isELIgnored=”false” 最好写上,省的遇到莫名其妙的版本问题,prefix是标签的缩略,可以自定义
JSTL
引入方式
步骤1:在pom.xml中添加以下配置
方式1:1.2及以上版本
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
方式2:1.2以下的版本需要
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
步骤2:在jsp头部引入
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
步骤三:在jsp中使用
<c:if test="${5>3}" var="string">
c:if测试
</c:if>
关于JSTL的具体使用方法参考学习菜鸟教程JSTL