EL表达式的主要作用

1)获取数据。EL使得获取JavaBean中的数据变得非常简单,也可以替换JSP页面中的脚本元素,从各种类型的web域中获取数据。

2)执行运算。利用EL表达式可以在JSP页面中执行一些基本的算术运算、关系运算、逻辑运算。

3)获取web开发常用对象,EL中定义了11个内置对象可以直接使用。

4)调用Java方法。EL表达式允许用户开发自定义EL函数,从而在JSP页面中通过EL表达式调用Java类的方法。

EL表达式的语法

以“${”开始,以“}”结束。

对于一系列的表达式,其取值将从左向右进行,计算结果的类型为String,并且连接在一起。

如果在定制标签的属性值中使用EL表达式,那么该表达式的取值结果字符串将会强制转换成该属性需要的类型

${标识符}
<!-- 如果 a=2,b=6,c=4,d=6 -->
${a+b}and${c+d} <!-- 返回 8and10 -->

EL表达中的关键字

这些关键字不能作为标识符

div mod               <!-- 算术运算符 -->
eq ne gt ge lt le <!-- 关系运算符 -->
and or not <!-- 逻辑运算符 -->
true false <!-- 逻辑值 -->
instanceof empty null

EL表达式可以返回任意类型的值,包括JavaBean

如果EL表达式的值是一个带有属性的对象,则可以使用“[]”或“.”运算符来访问该属性值。

${Object["propertyName"]}  <!-- 规范形式,任何情形下都能使用 -->
${Object.propertyName} <!-- 仅在propertyName是有效的Java变量名时使用(即字母、数字、下划线、$)-->
${header["host"]} <!-- 正确 -->
${header.host} <!-- 正确 -->
${header["accept-language"]} <!-- 正确 -->
${header.accept-language} <!--错误,accept-language不是有效的Java变量名-->

如果对象的属性也是一个对象,则可以继续使用“[]”或“.”访问第二个对象的属性。

${pageContext["request"]["servletPath"]}
${pageContext["request"].servletPath}
${pageContext.request.["servletPath"]}
${pageContext.request.request}

EL的取值规则

EL表达式的取值是从左向右进行的,对于expr-a["expr-b"],其EL表达式的取值方法如下:

首先计算 expr-a 得到 value-a,如果 value-a 为 null,则返回 null

然后计算 expr-b 得到 value-b,如果 value-b 为 null,则返回 null

如果 value-a 是 java.util.Map,则会查看 value-b 是否为 Map 的一个 key,若是则返回 value-a.get(value-b),若不是,则返回 null

如果 value-a 是 java.util.List 或者 array,分一下三种情况:

a、如果 value-b 强制转换为 int 失败,返回 null;

b、如果 value-a.get(value-b) 抛出 IndexOutOfBoundsException 异常,或者 Array.get(value-a, value-b) 抛出 ArrayIndexOutOfBoundsException 异常,则返回 null

c、否则,若 value-a 是一个 List,返回 value-a.get(value-b);若 value-a 是一个 array,返回 Array.get(value-a, value-b)

若果 value-a 不是一个 Map、List 或者 array,那么 value-a 必须是一个 JavaBean,此时需要将 value-b 强制转换成 String,如果 value-b 是 value-a 的一个可读属性,则要调用该属性的getter()方法从中返回值。

EL表达式取值的原理

在执行 ${标识符} 时,会调用pageContext.findAtrribute()方法,用标识符作为关键字,分别从page、request、session、application四个域中查找相应的对象并返回,找不到则返回空串""

在获取某个对象(包括JavaBean)的属性时,先将该属性的首字母变成大写,然后加上get前缀,拼凑成getter方法,通过反射将该对象构建出来,再对该对象执行getter方法,故JavaBean的属性名要小些,且要有getter方法。

使用EL运算符

算术运算符

+ - * / div % mod
${1+2*3} <!-- 结果为7 -->

逻辑运算符

&& and  <!-- 与 -->
|| or <!-- 或 -->
! not <!-- 非 -->

关系运算符

== eq  <!-- 等于 -->
!= ne <!-- 不等于 -->
> gt <!-- 大于-->
>= ge <!-- 大于等于 -->
< lt <!-- 小于 -->
<= le <!-- 小于等于 -->

条件运算符

${statement ? A : B} <!-- statement为true执行A,false执行B -->
${(sessionScope.loggedIn == null) ? "You have not logged in" : "You have logged in"}

empty 运算符

用来检查某个值是否为null或者empty

${empty X}  <!-- 如果X为null、长度为0的空字符串、空Map、空数组、空集合,将返回True,否则返回False -->

禁用EL表达式

第一种方法:在page指令中将的isELignored属性设为True

第二种方法:在部署描述符(web.xml)中修改<jsp-property-group>元素

<!--  第一种 -->
<%@ page isELIgnored="True" %>
<!-- 第二种 -->
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>

实例

一个JavaBean

package app04a.model;

public class Address {  // 一个JavaBean
private String streetName;
private String streetNumber;
private String city;
private String state;
private String zipCode;
private String country; public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
public String getStreetNumber() {
return streetNumber;
}
public void setStreetNumber(String streetNumber) {
this.streetNumber = streetNumber;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}

一个JavaBean

package app04a.model;

public class Employee {  // 一个JavaBean
private int id;
private String name;
private Address address; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}

Servlet作为控制器

package app04a.model;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import javax.servlet.RequestDispatcher;
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(name = "EmployeeServlet", urlPatterns = { "/","/employee" })
public class EmployeeServlet extends HttpServlet { // Servlet充当控制器 负责处理请求
private static final long serialVersionUID = 1L; public EmployeeServlet() {
super();
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Address address = new Address();
address.setStreetName("Rue D'Anjou");
address.setStreetNumber("5090B");
address.setCity("Brossard");
address.setState("Quebec");
address.setZipCode("A1A b2B");
address.setCountry("Canada"); Employee employee = new Employee();
employee.setId(1099);
employee.setName("Charles Unjeye");
employee.setAddress(address);
request.setAttribute("employee", employee); Map<String, String> capitals = new HashMap<String, String>();
capitals.put("China", "Beijing");
capitals.put("Austria", "Vienna");
capitals.put("Australia", "canberra");
capitals.put("Canada", "Ottawa");
request.setAttribute("capitals", capitals); RequestDispatcher requestDispatcher = request.getRequestDispatcher("/employee.jsp");
requestDispatcher.forward(request, response); // 将请求转发到JSP页面
} @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

JSP页面作为视图

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%-- JSP页面作为视图 负责显示 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Employee</title>
</head>
<body>
accept-language: ${header["accept-language"] } <br /> <%-- 使用EL隐式对象 --%>
session-id: ${pageContext["session"]["id"] } <br /> <%-- 使用EL隐式对象 --%>
employee: ${requestScope["employee"]["name"] }, ${employee["address"]["city"] } <br /> <%-- 访问JavaBean中的属性 --%>
capital: ${requestScope.capitals["Canada"] } <%-- 访问JavaBean中的属性 --%>
</body>
</html>

测试结果

编写EL函数

一般而言,编写EL函数需要以下三个步骤:

第一步:创建一个包含静态方法的public类。每个类的静态方法表示一个EL函数,这个类可以不需要实现任何借口或继承任何函数,这个类必须放在应用中的/WEB-INF/classes目录或者它的子目录下。

第二步:用fucntion节点在标签库描述器中注册这个函数。

第三步:要使用这个函数,必须将taglib指令中的uri属性指向标签库描述器,并指明使用的前缀。然后就可以在JSP页面中使用如下语法来访问该函数

${prefix:functionName(parameterList) }

function节点是taglib节点的下级节点,其有如下子节点

description         // 可选 标签说明
display-name // 在XML工具中显示的缩写的名字
icon // 可选,在XML工具中使用的icon节点
name // 函数的唯一名字
function-class // 该函数对应实现的java类的全名
fucntion-signature // 该函数对应实现的Java静态方法
example // 可选,使用该函数的实例说明
function-extension // 可以是一个或者多个节点,在XML工具中使用,用于提供该函数的更多细节

实例

创建一个包含静态方法的public类

package app06a.function;

public class StringFunctions {
public static String reverseString(String s) {
return new StringBuffer(s).reverse().toString();
}
}

用fucntion节点在标签库描述器中注册这个函数

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" >
<taglib>
<description>Function tag example</description>
<tlib-version>1.0</tlib-version>
<jsp-version>1.0</jsp-version>
<function>
<decription>Reverse a String</decription>
<name>reverseString</name>
<function-class>app06a.function.StringFunctions</function-class>
<function-signature>java.lang.String reverseString(java.lang.String)</function-signature>
</function>
</taglib>

使用这个函数

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/functions.tld" prefix="f" %> <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Testing EL Function</title>
</head>
<body>
${f:reverseString("Hello world") }
</body>
</html>

结果

最新文章

  1. alias导致virtualenv异常的分析和解法
  2. ZH奶酪:Java调用NLPIR汉语分词系统
  3. BSA混合分离分析法
  4. List、Map、Set
  5. Linux中修改环境变量及生效方法
  6. Shiro学习详解
  7. Runtime.getRuntime().exec(...)使用方法
  8. 【Maven】项目添加Maven类库依赖
  9. camstar --飞达上料
  10. android之View绘制
  11. faster-rcnn原理讲解
  12. SQLMAP注入教程-11种常见SQLMAP使用方法详解
  13. Mvaen仓库文件添加阿里镜像
  14. scrapy学习笔记之hello world
  15. 5、原生jdbc链接数据库实例-自动取款机
  16. 洛谷 P3951 小凯的疑惑
  17. Jenkins不同job之间传递参数
  18. c++中的c_str()用法
  19. 【Python】启动迅雷下载
  20. docker使用以及dockerfile编写

热门文章

  1. Swagger2
  2. PUDN用户名与密码
  3. SpringBoot配置logback
  4. C library:&lt;cctype&gt;(ctype.h)
  5. gitlab-ce 安装、汉化与阿里邮箱配置(注意是CE)
  6. js实现右击
  7. python基础入门学习1
  8. poj3279(枚举)
  9. 数论----gcd和lcm
  10. SideBar 选择城市时右侧边上的 选择bar