表达式语言(EL).docx_第1页
表达式语言(EL).docx_第2页
表达式语言(EL).docx_第3页
表达式语言(EL).docx_第4页
表达式语言(EL).docx_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

表达式语言(EL)表达式语言(Expression Language,EL)是JSP 2.0中引入的性特性,在JSP中使用EL表达式可以获取并显示页面数据。可以将业务逻辑编写在JavaBean中,然后搭配、来取得、生成JavaBean对象,设置或取得JavaBean的值,这样有助于减少页面上Scriptlet的分量。对于JSP中一些简单的属性、请求参数、报头与Cookie等信息的取得,一些简单的运算或判断,则可使用表达式语言(EL)来处理,甚至可以将一些常用的公用函数编写为EL函数,这对于网页上的Scriptlet又可以有一定分量的减少。JSP 2.0之后,EL已经正式纳入成为标准规范之一,可以在JSP网页中直接使用EL。若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器(如至少Tomcat 6)。EL表达式可以直接用在JSP页面的静态文本中,也可以作为JSP标签的属性值来使用。EL主要作用有:获取数据、执行运算、获取web开发常用对象、调用Java方法。1、EL简介EL语法很简单,主要的语法结构:$expression,(所有的EL都是以$ 为起始、以 为结尾的)。有效表达式可以包含字面值(Java中合法的常量,如任何由单引号或双引号限定的字符串、true、false、null、Null、数值等)、运算符、变量(对象引用)和函数调用。 $sessionScope.user.sex 或 $user.sex相当于JSP Scriptlet的写法如下:User user = (User)session.getAttribute(user);String sex = user.getSex( );直接来改写下面的add.jsp页面,其中编写了以下Scriptlet:如果使用EL,则可以优雅地用一行代码来改写,甚至加强这段Scriptlet。例如:JSPDemo add2.jsp加法网页$param.a + $param.b = $param.a + param.bEL是使用$与来包括所要进行处理的表达式,可使用点运算符(.)指定要存取的属性,使用加号(+)运算符进行加法运算。param是EL隐含对象之一,表示用户的请求参数,param.a表示取得用户所发出的请求参数a的值。 EL可进行自动转变类型。$param.count + 20相当于String str_count = request.getParameter(count);int count = Integer.parseInt(str_count);count = count + 20;在结果页面中可以看到,输入的请求参数自动转换为基本类型并进行运算,且在结果中还增加了显示操作数的功能。原来的add.jsp要有这样的结果,还得再增加Java代码。 EL优雅地处理了null值的情况,对于null值直接以空字符串加以显示,而不是直接显示null值,在进行运算时,也不会因此发生错误而抛出异常。 EL的点运算符还可以连续存取对象,就如同在Java代码中一般。例如,原先需要这么编写:方法:参数:IP:若是使用EL,则可以这么编写:方法:$pageContext.request.method参数:$pageContext.request.queryStringIP:$pageContext.request.remoteAddr pageContext也是EL的隐含对象之一,通过点运算符之后接上xxx名称,表示调用getXxx()方法。如果必须转换类型,EL也会自行处理,而不用像编写JSP表达式元素时,必须自行做转换类型的动作。 可以使用page指示元素的isELIgnored属性(默认是false),来设置JSP网页是否使用EL。会这么做的原因可能在于,网页中己含有与EL类似的$语法功能存在,例如使用了某个模板(Template)框架之类。也可以在web.xml中设置标签为true来决定不使用EL。例如:.*.jsptrue.web.xml中的是用来默认符合的JSP网页是否使用EL。如果web.xml中的与page指令元素的isELignored设置都没有设置,如果web.xml是2.3或以下的版本,则不会执行EL,如果是2.4或以上的版本,则会执行EL。如果JSP网页使用page指令元素的isELignored设置是否支持EL,则以page指令元素的设置为主,不管web.xml中的的设置是什么。EL的保留字:and、eq、gt、true、or、ne、le、false、no、lt、ge、null、instanceof、empty、div、mod。2、使用EL取得属性(.与 运算符)EL 提供“.”和“”两种运算符来取数据。“.”运算符用来访问JavaBean对象的属性值或者是Map对象的一个键值,如:$。“”可以访问JavaBean对象的属性值、数组对象的元素、List对象的元素以及是Map对象的一个键值,如:$username或$username。当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用“ “。例如:$user.My-Name应当改为$userMy-Name 。如果要动态取值时,就可以用“ “来做,而“.“无法做到动态取值。例如:$sessionScope.userdata中data 是一个变量。下列两者所代表的意思是一样的:$sessionScope.user.sex 等于 $sessionScope.usersex. 和 也可以同时混合使用,如下:$sessionScope.shoppingCart0.price可以在JSP中将对象设置至page、request、session或application范围中作为属性,基本上是通过setAttribute()方法设置属性,使用getAttribute()取得属性,但这些方法调用必须在Scriptlet中进行。如果不想编写Scriptlet,可以考虑使用,与。不过在使用上,语法仍是较为冗长。如果只是要“取得”属性,使用EL则可以更为简洁。例如:登录成功如果使用EL来编写,则可以修改如下:$ 登录成功在EL中,可以使用EL隐含对象指定范围来取属性,EL隐含对象将在稍后介绍。EL存取变量数据的方法很简单,例如:$ ,它的意思是取出某一范围中名称为的变量。若不指定属性的存在范围,则默认是以page、request、session、application的顺序来寻找EL中所指定的属性,假如全部的范围都没有找到时,就回传null。以上例而言,就是在page范围中找到了user属性,点运算符后跟随着name,表示利用对象的getNarne()方法取得值,而后显示在网页上。如果EL访问的对象是个数组对象,则可以使用运算符来指定索引以存取数组中的元素。例如,若网页的某处在请求范围中设置了数组作为属性:如果现在打算取出属性,并访问数组中的每个元素,则可以如下使用EL:名称一:$ arrayO 名称二:$ array1 名称三:$ array2 不仅数组对象可以在中指定索引来访问元素,如果属性是个List类型的对象,也可以使用运算符指定索引来进行访问元素。点运算符(.)与运算符需要特别说明。在某些情况下,可以使用点运算符(.)的场合,也可以使用运算符。以下先进行归纳:如果使用点(.)运算符,则左边可以是JavaBean或Map对象。如果使用运算符,则左边可以是JavaBean、Map、数组或List对象。所以不只可以使用点(.)运算符来取得JavaBean属性,也可以使用运算符。例如,可以用点(.)运算符取得User的name属性:$也可以使用运算符采取得User的name属性:$username如果想取得Map对象中的值,点(.)运算符或运算符都可以使用。例如,网页中若有某个地方有以下代码:%Map map = new HashMap)();map.put(user,caterpillar);map.put(role,admin);request.setAttribute(login, map);%则可以在网页某处使用点运算符取得Map中的值:User:$login.user User:$login.role 也可以在网页某处使用运算符取得Map中的值:User:$loginuser User:$loginrole 基本上,当左值是Map对象时,建议使用运算符,因为如果设置Map时的键名称有空白或点字符时,这是可以正确取得值的方式。例如:%Map map = new HashMap();map.put(user name,caterpillar);map.put(local.role,admin);request.setAttribute(login, map);%.User:$loginuser name User:$loginlocal.role 运算符的右边,除了可以是JavaBean、Map外,也可以是数组或List类型的对象。之前示范过数组的例子,以下则是一个List的例子:%List names = new ArrayList();names.add(caterpillar);names.add(momor);request.setAttribute(names, names);%.User 1: $names0 User 2: $names1 虽然可以在指定索引时使用双引号,如$names0,不过一般指定索引不会这么特别写。事实上,当运算符是使用双引号()指定时,就是作为键名或索引来使用。如果运算符中不是使用双引号,则会尝试做运算,结果再给来使用。例如:%List names = new ArrayList();names.add(caterpillar);names.add(momor);request.setAttribute(names, names);%User:$namesparam.index 在这个范例的EL中,使用了param.index,param是EL隐含对象,表示请求参数,这个范例会先寻找参数中index的值,让后再作为索引值给使用。所以如果请求时使用了index=0,则显示caterpillar,若index=1,则显示momor。所以,中也可以进行嵌套。例如:%List names = new ArrayList();names.add(caterpillar);names.add(momor);request.setAttribute(names, names);Map datas = new HashMap();datas.put(caterpillar,caterpillars data);datas.put(momor,momors data);request.setAttribute(datas, datas);%.User:$datasnamesparam.index 根据EL,如果请求时使用了index=0,则会取得names中索引0的值caterpillar,然后用取得的值作为键,再从datas中取得对应的caterpillars data。3、EL隐含(内置)对象在EL中提供有11个隐含对象(Implicit Object),其中除了pageContext隐含对象对应javax.servlet.jsp.PageContext之外,其他隐含对象都是对应java.util.Map类型。类别对象描述JSP页面上下文pageContext引用当前JSP页面的pageContext内置对象作用域pageScope获得页面作用范围中的属性值,相当于pageContext.getAttribute()requestScope获得请求作用范围中的属性值,相当于request.getAttribute()sessionScope获得会话作用范围中的属性值,相当于session.getAttribute()applicationScope获得应用程序作用范围中的属性值,相当于application.getAttribute()请求参数param获得请求参数的单个值,相当于request.getParameter()paramValues获得请求参数的一组值,相当于request.getParameterValues()HTTP请求头header获得HTTP请求头中的单个值,相当于request.getHeader()headerValues获得HTTP请求头中的一组值,相当于request.getHeadersValues()Cookiecookie获得请求中的Cookie值初始化参数initParam获得上下文的初始参数值(1)、pageContext隐含对象:对应于javax.servlet.jsp.PageContext类型,PageContext本身就是个JavaBean,只要是getXxx()方法(参考API),就可以用$pageContext.xxx来取得。可以使用 $pageContext来取得其他有关用户要求或页面的详细信息。Expression说明$pageContext.request.queryString 取得请求的参数字符串$pageContext.request.requestURL 取得请求的URL,但不包括请求之参数字符串$pageContext.request.contextPath 服务的web application 的名称$pageContext.request.method$pageContext.request.method 取得HTTP 的方法(GET、POST)$pageCtocol取得使用的协议(HTTP/1.1、HTTP/1.0)$pageContext.request.remoteUser 取得用户名称$pageContext.request.remoteAddr 取得用户的IP 地址$pageContext.session.new判断session是否为新的,所谓新的session,表示刚由server产生而client尚未使用$pageContext.session.id取得session 的ID$pageContext.servletContext.serverInfo 取得主机端的服务信息$pageContext.exception.message 取得页面异常信息(2)、属性范围相关隐含对象:与属性范围相关的EL隐含对象有pageScope、requestscope、sessionScope与applicationScope,分别可以取得使用JSP隐含对象pageContext、request、session与application的setAttribute()方法所设置的属性对象。如果不使用EL隐含对象指定作用范围,则默认从pageScope的属性开始寻找。$sessionScope.username相当于String username = (String) session.getAttribute(username);注意:EL隐含对象pageScope、requestScope、sessionScope与applicationScope不等同于JSP隐含对象pageContext、request、session与application。EL隐含对象pageScope、requestScope、sessionScope与applicationScope仅仅代表作用范围。(3)、请求参数相关隐含对象:与请求参数相关的EL隐含对象有param与paramValues。举例来说,$pararm.user其作用相当于。paramValues则相当于request.getParameterValues(),可以取得窗体复选项的值,由于返回的是多个值,可以使用运算符来指定取得哪个元素,例如$paramValues.favorites0 就相当于。(4)、报头(Header)相关隐含对象:如果要取得用户请求的报头数据,则可以使用header或headerValues隐含对象。例如,$headerUser-Agent相当于,headerValues则相当于request.getHeaders()方法。(5)、cookie隐含对象:cookie隐含对象可用来取得用户的Cookie对象。$cookie.key取的是cookie对象,如访问cookie的名称和值,须$或$cookie.key.value。如在Cookie中设置了username属性,则可使用$cookie.username.value取得Cookie值。(6)、初始参数隐含对象:initParam可以用来取得web.xml中设置的ServletContent初始参数,也就是在中设置的初始参数。例如,$initParam.initCount的作用相当于。4、EL运算符使用EL可以直接进行一些算术运算、逻辑运算与关系运算,就如同在一般常见的程序语言中的运算。 empty运算符:$empty expression,判断expression的值是否是null、空字符串、空数组、空Map或空集合(作用于一个集合,若该集合不存在或集合中没有元素,其结果都为true)。 ?:是个三元运算符:?前为true就返回:前的值,若为false就返回:后的值。例如:$user!=null? : “” 算术运算符:有加法(+)、减法(-)、乘法(*)、除法(/或div)与求模(%或mod)。 逻辑运算符:有and、or、not。 关系运算符:有表示“小于”的及gt(Greater-than),表示“小于或等于”的=及ge(Greater-than-or-equal),表示“等于”的=及eq(Equal),表示“不等于”的!=及ne(Not-equal)。关系运算符也可以用来比较字符或字符串,而=、eq与!=、ne也可以用来判断取得的值是否为null。例子:表达式结果表达式结果$11$1 (4/2) 或 $1 gt (4/2) false$1.2 + 2.33.5$4.0 = 3 或 $4.0 ge 3true$1.2E4 + 1.4120001.4$4 = 3 或 $4 le 3false$-4 2-6$100.0 = 100或 $ 100.0 eq 100 true$21 * 242$(10*10) != 100或 $ (10*10) ne 100 false$3/4 或 $3 div 40.75$a hitfalse$(10%4或 $10 mod 42$ 4 3 (如果操作数是一个代表数字的字符串,则会尝试解析为数值再进行运算)true$ (1=2) ? 3 : 4 4$true and falsefalse$empty(user)true$true or falsetrue$not truefalseEL运算符的执行优先级与Java运算符对应,也可以使用括号()来自行决定先后顺序。在EL表达式计算过程中,会遇到许多奇怪的问题,在此总结一下:1、所有的整数数字字面量都是Long类型的;2、所有小数字面量都是Double类型的;3、或声明的是字符串,即也是字符串,非char;4、比较时都是equals比较。el.jspInsert title hereage: $sessionScope.customerage name: $sessionS age: $customer.age score: $param.score + 11score:time: $applicationScope.time.time %- -%score: $param.score %- -%names: $paramV %- -% contextPath: $pageContext.request.contextPath sessionId: $pageContext.session.id sessionAttributeNames: $pageContext.session.attributeNames initParam: $initParam.initName Accept-Language: $headerAccept-Language JSESSIONID: $cookie.JSESSIONID.name - $cookie.JSESSIONID.value $param.score 60 ? 及格 : 不及格 % List names = new ArrayList();names.add(abc);request.setAttribute(names, names);%names is empty: $empty requestSs 5、自定义EL函数如果设计了一个Util类,其中有个length()静态方法可以将传入的Collection长度返回。例如,原先可能这么使用它:如果someList实际上是个List接口实现,而其长度为10,则会返回结果10。但是这样要编写Scriptlet,如果函数的部分也可以使用EL来调用,以下也许是想要的编写方式:$ util:length(requestScope.someList) 这样的写法着实简洁许多,如果这是想要的需求,则可以自定义EL函数来满足这项需求。EL函数的本质是:提供一种语法允许在EL中调用某个类的静态方法。自定义EL函数的开发类似于标签的开发。自定义EL函数的开发的三个步骤如下:(1)、编写函数处理类的静态方法,函数处理类是个普通类,它必须是个公有(public)类,而想要调用的方法必须是公有、静态方法。实际上这个步骤可以省略,完全可以直接使用JDK或其他项目提供的类,只有这些类包含共有的静态方法即可。例如,Util类可能是这么编写的:JSPDemo Util.javapackage cc.openhome;import java.util.Collection;public class Util public static int length(Collection collection) return collection.size();(2)、编写标签库描述符(tld)文件,在tld文件中描述自定义函数:与定义标签的方法类似。Web容器必须知道如何将这个类中的length()方法当作EL函数来使用,所以必须编写一个标签程序库描述(Tag Library Descriptor, TLD)文件,这个文件是个XML文件,后缀为*.tld。可以将这个TLD文件直接放在WEB-INF文件夹下或WEB-INF目录下的除了classes和lib目录之外的任意子目录中,这样容器会自动找到TLD文件并载入。如果要放在JAR文件中,设置的方式在后面章节介绍如何自定义标签库时还会说明。在这里为了简化,先将TLD文件放在WEB-INF文件夹下。TLD文件中的元素用指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。在元素下增加元素用于定义自定义EL函数;增加元素则用于自定义标签。每个元素有四个子元素:(非必须元素,用于描述EL函数)、(指定自定义EL函数的函数名)、(指定自定义EL函数的处理类的全类名)、(指定自定义EL函数对于的方法签名,方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔)。例如:JSPDemo openhome.tld 1.0 openhome http:/openhome.cc/util Collection Length length cc.openhome.Util int length(java.util.Collection) 在TLD文件中,重要的部分已在代码中直接标示。$util.length()的例子中,length名称就对应于标签的设置,而实际上length名称背后执行的类与真正的静态方法则分别由与来设置。至于标签则在JSP网页中会使用到,稍后就会了解其作用。(3)、在JSP中使用EL函数:先导入标签库,然后再使用函数:$prefix:method(params)。接着可以编写一个JSP来使用这个自定义EL函数。例如:JSPDemo elfunction.jsp自定义EL函式$ util:length(requestScope.someList) 在这里使用taglib指示元素告诉容器,在翻译这个JSP时,会用到对应uri属性的自定义EL函数,容器会寻找读入的TLD中,标签设置中有对应uri属性的名称,这就是刚才在openhome.tld中定义标签的目的。至于prefix属性则是设置前置名称,这样若JSP中有多个来自不同设计者的EL自定义函数,就可以避免名称冲突的问题。所以要使用这个自定义EL函数时,就可以用$util:length(.)的方式。提示:实际上在JSTL中包括EL函数库,它提供一些常用的EL函数,在JSTL的EL函数库不再使用时,就可以用这里的方式来自定义EL函数。JSTL是标准自定义标签库,这会在第7章中介绍如何使用。至于在JSTL不再使用时如何自定义标签,则会在JSTL说明。6、JSTL中的EL表达式由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,SUN公司针对于一些常见处理定义了一套EL函数库供开发者使用。这些EL函数在JSTL开发包中进行描述,因此在JSP页面中使用SUN公司的EL函数库,需要导入JSTL开发包,并在页面中导入EL函数库。在页面中使用JSTL定义的EL函数:字符串处理相关函数,简单地整理如下:n 改变字符串大小写:tolowerCase、toUppeCasen 取得子字符串:substring、substringAfter、substringBeforen 裁剪字符串前后空白:trimn 字符串取代:replacen 检查是否包括子字符串:startsWith、endsWith、contains、containsIgnoreCasen 检查子字符串位置:lndexOfn 切割字符串为字符串数组:splitn 连接字符串数组为字符串:joinn 替换XML字符:escapeXML1.fn:toLowerCase/fn:toUpperCase-String toUpperCase/toLowerCase(String input)fn:toLowerCase/ fn:toUpperCase函数将一个字符串中包含的所有字符转换为小/大写形式,并返回转换后的字符串,它接收一个字符串类型的参数。例如fn:toLowerCase(Www.IT.org) 的返回值为字符串“”fn:toLowerCase()的返回值为空字符串3.fn:trim-String trim(String input)fn:trim函数删除一个字符串的首尾的空格,并返回删除空格后的结果字符串,它接收一个字符串类型的参数。需要注意的是,fn:trim函数不能删除字符串中间位置的空格。例如,fn:trim( www.i ) 的返回值为字符串“www.i ”。4.fn:length-int length(Object obj)fn:length函数返回一个集合或数组大小,或返回一个字符串中包含的字符的个数,返回值为int类型。fn:length函数接收一个参数,这个参数可以是标签的items属性支持的任何类型,包括任意类型的数组、java.util.Collection、java.util.Iterator、java.util.Enumeration、java.util.Map等类的实例对象和字符串。如果fn:length函数的参数为null或者是元素个数为0的集合或数组对象,则函数返回0;如果参数是空字符串,则函数返回0。 5.fn:split-String split(String input, String delimiters)fn:split函数以指定字符串作为分隔符,将一个字符串分割成字符串数组并返回这个字符串数组。fn:split函数接收两个字符串类型的参数,第一个参数表示要分割的字符串,第二个参数表示作为分隔符的字符串。例如,fn:split(, .)1的返回值为字符串“it”。6.fn:join-String join(String array, String separator)fn:join函数以一个字符串作为分隔符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串。fn:join函数接收两个参数,第一个参数是要操作的字符串数组,第二个参数是作为分隔符的字符串。如果fn:join函数的第二个参数是空字符串,则fn:join函数的返回值直接将元素连接起来。例如:假设stringArray是保存在Web域中的一个属性,它表示一个值为www,it,org的字符串数组,则fn:join(stringArray, “.)返回字符串“”fn:join(fn:split(www,it,org, ,), .) 的返回值为字符串“”7.fn:indexOf-int indexOf(String input, String substring)fn:indexOf函数返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。fn:indexOf函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,那么,不管第二个参数字符串在第一个参数字符串中出现几次,fn:indexOf函数总是返回第一次出现的索引值;如果第一个参数中不包含第二个参数,则fn:indexOf函数返回-1。如果第二个参数为空字符串,则fn:indexOf函数总是返回0。例如:fn:indexOf(,it) 的返回值为48.fn:contains、fn:containsIgnoreCase-boolean contains/containsIgnoreCase(String input, String substring)fn:contains函数检测一个字符串中是否包含指定的字符串,返回值为布尔类型。fn:contains函数在比较两个字符串是否相等时是大小写敏感的。fn:contains函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,则fn:contains函数返回true,否则返回false。如果第二个参数的值为空字符串,则fn:contains函数总是返回true。实际上,fn:contains(string, substring)等价于fn:indexOf(string, substring) !=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论