本篇讲解使用EL表达式来调用Java方法(自定义EL函数)和Sun公司开发的EL函数库。

  简单来说,我们在一个类中的某个方法,可以使用EL进行调用,这个能被EL表达式调用的方法称之为EL函数,但是这种方式必须满足以下两点要求:

  ① 在EL表达式中调用的只能是Java类的静态方法

  ② 这个Java类的静态方法需要在我们另外在自定义的TLD文件中描述

  满足以上两点才能被EL表达式调用。

语法:  ${prefix:方法名(参数列表) }

例1:使用EL函数来实现HTML语言的过滤转义

  在web工程中自定义一个HTMLFilter类,同时定义一个静态的filter方法:

 package com.fjdingsd.filter;
public class HtmlFilter { public static String filter(String message) { if (message == null)
return (null); char content[] = new char[message.length()];
message.getChars(0, message.length(), content, 0);
StringBuilder result = new StringBuilder(content.length + 50);
for (int i = 0; i < content.length; i++) {
switch (content[i]) {
case '<':
result.append("&lt;");
break;
case '>':
result.append("&gt;");
break;
case '&':
result.append("&amp;");
break;
case '"':
result.append("&quot;");
break;
default:
result.append(content[i]);
}
}
return (result.toString()); }
}

  这个类中的filter方法能将HTML语言转换为普通的字符串,当然这个类和方法在Tomcat中也有示例,路径为【Tomcat】--->【webapps】--->【examples】--->【WEB-INF】--->【classes】--->【utils】,找到HTMLFilter.java就是了。

  

  好了我们已经有静态的方法了,现在需要在TLD文件中对这个方法进行描述才能在JSP中使用。

  TLD文件需要在“WEB-INF”文件中创建和定义,在哪里找模板呢,依然可以到Tomcat中寻找。在【Tomcat】--->【webapps】--->【examples】--->【WEB-INF】--->【jsp2】中有一个“jsp2-example-taglib.tld”文件,我们就可以对这个文件复制其“首尾”啦。

  在web工程下建立“elfunction.tld”文件,从“jsp2-example-taglib.tld”文件模板中抄首抄尾,其中<function>标签也是我们需要的:

 <?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>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
<uri>elfunction</uri> <function>
<description>Converts Html to String</description>
<name>filter</name>
<function-class>com.fjdingsd.filter.HtmlFilter</function-class>
<function-signature>java.lang.String filter( java.lang.String )</function-signature>
</function>
</taglib>

  在TLD文件中要对某Java静态方法进行描述最重要的就是要定义<function>标签,在<function>标签下,<description>只是对该方法的描述,不是必需的;<name>指定在JSP上使用该EL函数时应该使用的标签名;<function-class>指定该方法所在的类,必需提供完整类名(包括包名);<function-signature>是方法签名,就是对所使用的静态方法的声明,所有的参数都必需指定完整类名,包括返回值类型和参数列表类型。

  好了,接下来我们在JSP页面中就可使用刚才定义好的EL函数了,当然,首先我们应该现在JSP上使用tablib指定导入标签库,并定义好标签前缀(prefix):

    <%@ taglib uri="elfunction" prefix="elfn" %>

最后再在JSP页面的主体中使用EL函数:

    ${elfn:filter("<a href='www.baidu.com'>百度</a>") }

在浏览器中观察:

  

这样,使用EL函数就将一个超链接过滤转义成普通的文本了。

  通过上面的例子,使用EL函数似乎和自定义标签一样,可以移除JSP中出现的Java代码,但是EL函数比自定义标签的不足之处在于,EL函数只能移除与web无法的方法,无法移除与web有关的方法,比如某些方法中含有HttpServletRequest、HttpServletResponse等等这样的对象,因为在定义静态方法的时候,我们无法使用到这些web对象,这些web对象都是由Tomcat服务器返回这些接口的实例对象的,这都是服务器中低层封装好的,我们平常使用静态方法根本无法获取,因此此时还是需要使用自定义标签的。

  Sun公司也帮我们制作了一个函数库,在这函数库中封装好了一些常用的EL函数,平时我们可以先看看在这个函数库中是否有满足我们需求的EL函数,如果没有再像上面一样自定义。

Sun公司定义的EL函数封装和描述在JSTL标签库中,因此在JSP页面中使用这个EL函数库时,应该先导入JSTL开发包,并在该页面中导入EL函数库。如果是使用JavaEE5.0以上的,JSTL包会自动导入,可以在【Java EE 5 Libraries】库中看到:

  

在这个“jstl-1.2.jar”中,查看其“META-INF”文件,有一个“fn.tld”文件,这个就是Sun公司封装在JSTL中的EL函数的TLD文件:

  

我们可以点击进去看看,这个tld文件中封装了所有Sun公司设计好的EL函数,同时也提供了taglib指令的uri,和推荐前缀(prefix):

  

那么我们在JSP页面中导入tablib指令时只要这两个信息即可:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

这样我们就可以在JSP页面中使用Sun公司开发好的EL函数了。

例2:   fn:toLowerCase函数

    ${fn:toLowerCase("AAA") }

输出:aaa。

例3:      fn:length()函数

    ${fn:length("aaa") }

输出:3

例4:  fn:length函数

     <%
request.setAttribute("arr", new String[5]);
%> ${fn:length(arr) }

输出:5

例5:使用JSTL与EL函数来遍历集合

  需同时导入JSTL与EL的tablib指令:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

在JSP主体中的代码如下:

     <%
ArrayList<String> list = new ArrayList<String>();
list.add("Ding");
list.add("LRR");
request.setAttribute("list", list);
%> <c:forEach var="i" begin="0" end="${fn:length(list)}">
${list[i] } <br>
</c:forEach>

在浏览器中观察:

  

例6:      fn:join函数

  fn:join函数第一个参数为字符串数组或集合,第二个参数为将该字符串数组或集合相连起来的分隔符。

     <%
String[] arr = {"www","fjdingsd","com"};
pageContext.setAttribute("arr", arr);
%> ${fn:join(arr,".") }

输出:www.fjdingsd.com

  注:如果fn:join函数的第二个参数为空字符串“”,那么将会把所有元素直接相连。

例7:    fn:contains函数

  fn:contains函数检测一个字符串中是否包含指定的字符串,返回值为布尔类型。注意,fn:contains函数只能检测字符串,不能以数组来检测,如果第二个参数为空字符串“”,那么fn:contains函数总是返回true。

    ${fn:contains("fjdingsd","fj") }

输出:true。

  注:fn:contains函数是大小写敏感的,如果要忽略大小写,请使用fn:containsIgnoreCase函数。

例8:  取出表单类型为checkbox的数据回显

  模拟在表单提交失败时,对于表单中类型为“checkbox”的表单项的数据,可以使用EL函数从重新转发回的request获取数据,经过一定的处理,使该页面中的表单项数据重新显示:

     <%
request.setAttribute("hobbies", new String[]{"sing","dance"});
%> <input type="checkbox" name="hobbies" value="sing"
${fn:contains(fn:join(hobbies,""),"sing")?'checked':'' } >唱歌 <br>
<input type="checkbox" name="hobbies" value="dance"
${fn:contains(fn:join(hobbies,""),"dance")?'checked':'' }>跳舞 <br>
<input type="checkbox" name="hobbies" value="game"
${fn:contains(fn:join(hobbies,""),"game")?'checked':'' }>游戏 <br>
<input type="checkbox" name="hobbies" value="movie"
${fn:contains(fn:join(hobbies,""),"movie")?'checked':'' }>电影 <br>

在浏览器中观察:

  

例9:   fn:escapeXml函数

  功能与例1相同,对HTML语言进行过滤转义成字符串。

    ${fn:escapeXml("<a href='www.baidu.com'>百度</a>") }

浏览器中观察:

  

例10:自定义字符串连接的EL函数(因为在EL表达式中不支持使用”+”作为字符串的连接符)

  在一个类中定义字符串连接的静态方法:

 public class MyElFunctions {

     public static String connectString(String str1,String str2) {
return str1+str2;
} }

在【WEB-INF】中自定义TLD文件中声明这个方法,同时定义自己的uri:

 <?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>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
<uri>myelfunction</uri> <function>
<description>Connect two Strings</description>
<name>connect</name>
<function-class>com.fjdingsd.elfunctions.MyElFunctions</function-class>
<function-signature>java.lang.String connectString( java.lang.String , java.lang.String )</function-signature>
</function>
</taglib>

在JSP页面中加入taglib声明:

    <%@ taglib uri="myelfunction" prefix="elfn" %>

在JSP页面中的主体代码为:

     <%
User u = new User();
u.setUsername("fjdingsd");
session.setAttribute("user", u);
%> ${sessionScope.user!=null ? elfn:connect("欢迎您: ",user.username):'' }

在浏览器中观察:

  

  通常,我们在项目中会有专门的一个类来作为EL函数的方法实现类,在这个类中都是定义EL函数的静态方法。

  在JSTL包中的fn.tld文件中还有很多EL函数,这里就不再一一介绍了,如果我们有需要,可以在这个文件中查看,基本每个函数都有示例。

  EL表达式到这里就差不多介绍完了,主要就是这四大功能(获取数据,执行运算,使用隐式对象,调用Java方法),最后就来简单说明一下EL表达式的注意事项:EL表达式是JSP2.0规范中的一门技术,因此若想正确解析EL表达式,必须使用Servlet2.4/JSP2.0技术及以上的WEB服务器。

  有些Tomcat服务器不能使用EL表达式的话,要么将Tomcat升级6及以上的版本,要么在JSP页面中加入page指令<%@ page isELIgnored="false" %>

EL表达式(3)的更多相关文章

  1. jsp页面无法识别el表达式的解决方案

    今天在写一个springmvc的小demo时,碰到一个问题,在jsp页面中书写为${user.username}的表达式语言,在浏览器页面中仍然显示为${user.username},说明jsp根本不 ...

  2. El表达式的关系运算符

    El表达式的关系运算符: ==  对应  eq !=   对应  ne >    对应  gt <    对应  It

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

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

  4. EL表达式的算术运算

    一个例子--乘法运算 ${book.bookCount * book.bookPrice } 两个不同对象的EL表达式的算术运算同理 ${student.studentNum * book.bookP ...

  5. EL表达式杂项

    1.<%@ page isELIgnored="false" %> 是否忽略EL表达式,如果值为ture,那么  ${..}这样的会直接原样输出,不会进行EL表达式计算 ...

  6. c:out标签和el表达式与跨域攻击XSS

    很多时候,在JSP中我们喜欢用EL表达式输出信息,但是最近发现这个确实存在个问题:XSS即跨域攻击. 下面看个例子: <c:out value="${student.name}&quo ...

  7. JavaWeb:EL表达式

    JavaWeb:EL表达式 说明 1.Expression Language语言,一种用于JSP文件中的数据访问的语言. 2.能够简化JSP文件中该数据访问的代码,可用来替代传统的基于<%= % ...

  8. 重温JSP学习笔记--El表达式

    el表达式是jsp内置的表达式语言,jsp从jsp2.0开始,就不再提倡使用java脚本,而是用el表达式和动态标签来替代,而el表达式主要替代的是jsp中的<%=....%>,也就是说e ...

  9. Spring2.0-applicationContext.xml中使用el表达式给实体类属性赋值被当成字符串-遁地龙卷风

    (-1)写在前面 这两天读<javaweb开发王者归来>,学到Spring的PropertyPlaceholderConfigurer时出现一个问题,我已${jdbc.name}的形式赋值 ...

  10. Javaweb学习笔记——EL表达式

    一.前言 EL表达式是什么? 简而言之,可以这样理解,EL表达式全名为:Exprexxsion Language,原先是JSTL 1.0为了方便存取数据而定义的语言,到了JSTL 2.0便正式成为标准 ...

随机推荐

  1. 【.Net基础拾遗】品味OO继承

    0X1 引言 提起面向对象,每个人都有不同的见解.但提的最多的无非就是:对象.封装.继承.多态.差不多就是这些元素构成了面向对象设计开发的基本逻辑.面向对象编程,“对象”指的是什么?这里的" ...

  2. USB键盘数据解析

    以前用过的一个嵌入式设备使用USB键盘作为输入.当时还研究了一下USB协议,现在都快忘得差不多了.这里整理一下当时找到的关于USB键盘数据方面的资料. 主机与USB键盘建立连接后,定时从键盘获取8字节 ...

  3. go - 变量和常量

    1.定义变量 goLang中定义变量的方式很多 先声明再使用:如果定义的变量未使用编译时会报错 a. /*定义单个变量*/ var varName type //定义一个 type 类型的变量 var ...

  4. BZOJ 3359: [Usaco2004 Jan]矩形( dp )

    数据范围这么小..怎么乱搞都可以吧... 先排序一遍然后O(n²) dp --------------------------------------------------------------- ...

  5. 1076: [SCOI2008]奖励关( dp )

    期望状压dp.... ------------------------------------------------------------------ #include<cstdio> ...

  6. XSS学习笔记(四)-漏洞利用全过程

    <script type="text/javascript" reload="1">setTimeout("window.location ...

  7. js入门——Dom基础

    DOM=DocumentObject Model,文档对象模型. Dom有三个不同的部分. 1.核心DOM 也是最基础的文档结构的标准模型 2.XMLDOM 针对XML文档的标准模型 3.HTML D ...

  8. em换算px

    一般浏览器默认的1em=16px,所以常用字体大小如下: 10px=0.625em 12px=0.75em 14px=0.875em 16px=1em 18px=1.125em 20px=1.25em ...

  9. Eclipse一个打开文件夹目录插件——Open In Explorer

    MyEclipse开发的都常用到其中一个"Open In Explorer"的小插件,可以直接在Windows资源管理器中打开选中文件所在的目录,工具虽小,但我们经常需要用到它 由 ...

  10. 拥抱AngularJS

    文中一些地方AngularJS简称ng 简介: ng诞生于2009年,由Misko Hevery等创建,后被Google收购,为克服HTML在构建应用上的不足而设计. 是一款优秀的前端JS框架,核心特 ...