13.1. 再谈el(Expression Language)

我们已经知道el是jsp-2.0规范的一部分,tomcat-5.x版本以上都已经能够支持jsp-2.0规范,但在更低版本的tomcat和webphere,weblogic中还是无法使用这一便捷方式。

其实我们也可以选择在jsp中禁止使用el表达式,使用jsp指令(directive)可以对禁用某一个jsp中的el表达式。

禁用之后的el表达式会以原样显示出来,如下图所示。

为了对照,我们还在13-01下放了一个可以正常使用el表达式的例子,运行效果如下图显示。

在13-01/index.jsp中禁用el表达式,是使用了isELIgnore="true"这样一条jsp指令(directive),请注意大小写。

<%@ page isELIgnored="true" %>
<%
pageContext.setAttribute("hello", "Hello World");
%> ${hello}

还有一种批量禁用el的方法,我们可以在WEB-INF/web.xml中使用jsp-property-group标签批量禁用el,我们在13-02/WEB-INF/web.xml中进行如下配置。

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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-app_2_4.xsd"
version="2.4"> <jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config> </web-app>

这样就会禁用所有以.jsp后缀的请求中的el表达式,使用这种方式需要注意两点。

  1. jsp-property-group标签是jsp-2.0中新增功能,如果你使用低版本的web.xml(2.3或以下)就不能使用这个标签了。

  2. 设置jsp-config会影响jsp生成servlet的过程,如果程序修改时已经有jsp转换成servlet并缓存在work目录下,那么修改后需要先清除缓存,才能看到效果。

实际上还有第三种方法可以禁用掉所有jsp中的el表达式,那就是把web.xml定义为2.3版。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
</web-app>

这个就是13-03/WEB-INF/web.xml的定义,定义了web-app的版本号是2.3,这样一来所有的jsp都无法使用el表达式了,因为el表达式是2.4版才开始支持的功能。

13.2. 作用域

使用el的时候,默认会以一定顺序搜索四个作用域,将最先找到的变量值显示出来。

如果我们有${username}这样一个正则表达式,它回去依次调用pageContext.getAttribute("username") -> request.getAttribute("username") -> session.getAttribute("username") -> application.getAttribute("username"),只要找到某一个不为空的值就立刻返回。

这样的确方便我们的操作,但是随之也出现了另外一个问题,如果pageContext和request中有同名变量,但是我想取得request中的变量该如何是好呢?这就需要为el表达式引入作用域的概念了。

${pageScope.username}

${requestScope.username}
        

我们可以直接访问13-04这个应用,看看el表达式支持的所有对象。

下面我们分别对每个作用域对象进行讲解。

表 13.1. el中的作用域

el中的作用域 对应关系
pageContext 当前页的pageContext对象
pageScope 把page作用域中的数据映射为一个map对象
requestScope 把request作用域中的数据映射为一个map对象
sessionScope 把session作用域中的数据映射为一个map对象
applicationScope 把application作用域中的数据映射为一个map对象
param 对应request.getParameter()
paramValues 对应request.getParameterValues()
header 对应request.getHeader()
headerValues 对应request.getHeaderValues()
cookie 对应request.getCookies()
initParam 对应ServletContext.getInitParamter()

例子中的${pageContext.request.contextPath}返回的是request.getContextPath()的值,在此例中就是/13-04,我们经常使用这个来拼接jsp中的绝对路径。

这里的${pageContext.request.contextPath}是一种特殊用法,不能使用${request.contextPath}的形式替代。

pageScope,
requestScope, sessionScope,
appliationScope都可以看作是Map型变量,调用其中的数据可以使用${pageScope.name}或${pageScope["name"]}的形式,这两种写法是等价的。

在某些情况下只能使用${pageScope["content-type"]},这里不能写成${pageScope.content-type},jsp无法解析连字符(-)会出现错误。

需要注意的是${paramValues.name}得到的是一个字符串数组,如果需要获得其中某个值,还需要使用${paramValues.name[0]}指定数组中的索引。

这与下面的${headerValues.name}是相似的。

${header.name}会取得http请求中的header参数,现实工作中很少用到这里的数据。

例子中使用Host是指请求访问的主机地址,包括ip和端口号。而Referer比较有趣,如果用户通过超链接跳转过来的,Referer会保存上次访问页面的地址,我们就可以通过它来统计哪些用户是从哪里转来的了。

${cookie.name}将获得对应cookie的对象,比如我们用jsp将一段cookie发送给客户端。

Cookie cookie = new Cookie("username", "Username in cookie");
response.addCookie(cookie);

创建一个名称为username,值为"Username in cookie"的Cookie对象,然后发送给客户端。

然后我们就可以使用${cookie.username}获得这个cookie了,${cookie.username.name}获得cookie名称,${cookie.username.value}获得cookie值。

ServletContext.getInitParamter()指的应用的初始变量,这些变量都是定义在web.xml中的。

<context-param>
<param-name>username</param-name>
<param-value>username with context param</param-value>
</context-param>

${initParam.username}就会得到这里的变量值。

以上都是死记硬背的东西,建议实际用到的时候翻看一下就好了,演示代码都放在13-04下,为了获得param和cookie还要点击一下最下边的连接才可以。

13.3. 运算符

el表达式中支持java中所有的操作符,并且还有一些扩展,下面我们简要做一下对照。

表 13.2. 加减乘除四则运算

符号 说明
+
-
*
/或div
%或mod 求余

表 13.3. 比较运算

符号 说明
==或eq 相等(equals)
!=或ne 不相等(not equals)
<或lt 小于(less than)
>或gt 大于(greater than)
<=或le 小于等于(less than or equals)
>=或ge 大于等于(greater than or equals)

表 13.4. 逻辑运算

符号 说明
&&或and 逻辑和
||或or 逻辑或
!或not 取反

表 13.5. 特殊运算

符号 说明
empty 是否为null或空字符串
? : 三元运算符

下面上所有运算符的显示结果,顺便说一下如果想在jsp中显示${name}而不让jsp把它当作el计算出来,可以写成\${name},这样最后显示的结果就是${name}了。

第 13 章 剖析el表达式的更多相关文章

  1. 《python解释器源码剖析》第13章--python虚拟机中的类机制

    13.0 序 这一章我们就来看看python中类是怎么实现的,我们知道C不是一个面向对象语言,而python却是一个面向对象的语言,那么在python的底层,是如何使用C来支持python实现面向对象 ...

  2. Java Web程序设计笔记 • 【第9章 EL表达式】

    全部章节   >>>> 本章目录 9.1 EL 表达式基础 9.1.1 EL 表达式简介 9.1.2 EL 表达式的定义 9.1.3 使用 EL 访问变量 9.1.4 使用 E ...

  3. 13 JSP、MVC开发模式、EL表达式和JSPL标签+软件设计架构---学习笔记

    1.JSP (1)JSP概念:Java Server Pages 即java服务器端页面可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码用于简化书写!!! (2)原理 ...

  4. 实战2--应用EL表达式显示投票结果

    (1)编写index.jsp页面,用于收集投票信息 <%@ page language="java" pageEncoding="GBK"%> &l ...

  5. 第 13 章 StringTable详解

    目录 第 13 章 StringTable 1.String 的基本特性 1.1.String 概述 1.2.String 的基本特征 1.3.String 的底层结构 2.String 的内存分配 ...

  6. java web学习总结(三十一) -------------------EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  7. EL表达式与JSTL

    内容包括 EL表达式 EL函数库 JSTL 核心标签库 格式化标签库 SQL标签库 XML标签库 自定义标签库 EL表达式 EL是Expression Language的是缩写,是JSP页面编写的一种 ...

  8. el表达式的function标签

    使用el调用Java方法 1:EL表达式语法允许开发人员开发自定义函数,以调用java类的方法. ~示例:${el:method(params)} ~在EL表达式中调用的只能是java类的静态方法. ...

  9. JSP页面用EL表达式 输出date格式

    JSP页面用EL表达式 输出date格式 1.头上引入标签 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix ...

随机推荐

  1. 对于Eclipse的正确用法

    有时候我们刚刚修改了工程里的文件 但是启动的时候它硬是说你有东西没有声明 而那个东西又明明在那里.. 这时候我们可以认为实际与它调用的工程关系文件(我假想的) 不同步.. 我们可以通过clean功能来 ...

  2. Liferay 6.2 改造系列之十三:修改用户编辑页面表单内容

    为简化用户编辑,删除无用内容: 在/portal-master/portal-impl/src/portal.properties文件中,有如下配置: # # Input a list of sect ...

  3. shell-bash学习02运算、拼接、重定向

    运算 let操作 可以直接执行基本的算术操作;使用时,变量名之前不需要再添加$; #!/bin/bash no1=4; no2=5; let result=no1+no2 echo $result 自 ...

  4. 从Sql server 2008获取表字段属性信息,注释信息

    select   b.[value] from sys.columns a left join sys.extended_properties b on a.object_id=b.major_id  ...

  5. 我的DbHelper数据操作类

    其实,微软的企业库中有一个非常不错的数据操作类了.但是,不少公司(起码我遇到的几个...),对一些"封装"了些什么的东西不太敢用,虽然我推荐过微软的企业库框架了...但是还是要&q ...

  6. ie不支持getElementsByName的解决办法

    在chrome下getElementsByName运行正常,可在IETester7~11下都不支持  w3c规范中getElementsByName是按着name属性进行检索的,而MS的IE却是按着i ...

  7. xampp的Apache无法启动解决方法

    XAMPP Apache 无法启动原因1(缺少VC运行库): 这个就是我遇到的问题原因,下载安装的XAMPP版本是xampp-win32-1.7.7-VC9,而现有的Windows XP系统又没有安装 ...

  8. .net平台下C#socket通信(上)

    在开始介绍socket前先补充补充基础知识,在此基础上理解网络通信才会顺理成章,当然有基础的可以跳过去了.都是废话,进入正题. TCP/IP:Transmission Control Protocol ...

  9. 最长上升子序列[LIS]

    算法原理很简单,不再赘述,这里贴一个函数模板,传入的参数为序列首尾元素的指针. template<typename T> int LIS_nlogn(T * s, T * e) { ; T ...

  10. unity awake start 的区别

    void Awake (){ } //初始化函数,在游戏开始时系统自动调用.一般用来创建变量之类的东西. void Start(){ } //初始化函数,在所有Awake函数运行完之后(一般是这样,但 ...