EL(表达式语言)

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>

结果

 

posted on 2018-10-26 16:12  0820LL  阅读(834)  评论(0编辑  收藏  举报

导航