简介
EL原本是JSTL1.0中的技术(所以EL和JSTL感情如此好就是自然的了),但是从JSP2.0开始,EL就分离出来纳入了JSP的标准了。但是EL函数还是和JSTL技术绑定在一起。下面将介绍如何自定义EL函数,以及JSTL中的EL函数。
自定义EL函数虽然用得很少(JSTL自带的EL函数已经够用了),但是可以帮助理解自定义tag打下基础。
自定义EL函数
一、编写Java实现函数
必须是public类中的public static 函数,每一个静态函数就可以成为一个EL函数。
必须在工程的classes下,(Eclipse 的src下),可以放到单独的包里。
package custom; public class Functions { //反转一个字符串 public static String reverseString(String str) { return (new StringBuilder(str).reverse().toString()); } //返回字符串的长度 public static Integer stringLength(String str) { return str.length(); } }
二、编写.tld文件(tag library descriptor 标签库描述符),注册EL函数,使之可在JSP中被识别。
.tld文件可以放在 WEB-INF下,或者是WEB-INF下的子目录下
【这里我取名为mytag.tld 】
WEB-INF --mytag.tld <!--或者 --> WEB-INF --subfolder --mytag.tld
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- tld文件是一个XML文件,他定义了一个tag library。 这个文件描述了一个标签库的相关信息。 每一个tld文件可以定义多个EL函数,还有自定义标签。 --> <description>这是我自己的标签库哦</description> <!-- 标签库的说明信息 --> <tlib-version>1.0</tlib-version> <!-- 定义这个标签库的版本 --> <!-- 定义函数库作者推荐的(首选的)名称空间前缀,即在JSP页面通过taglib指令导入标签库时,指定的prefix的值, 当然,使用者可以完全不使用这个值,而是其它的值。 例如JSTL核心库前缀是一般是c 。 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> --> <short-name>nutlee</short-name> <!-- 标识这个在互联网上的唯一地址,一般是作者的网站,这个网址可以根部不存在对应的资源,但一定要是唯一的。这里的值用在将在 taglib 指令中 uri的值--> <uri>http://www.nutlee.com/jsp-custom</uri> <!-- 没一个function结点 定义一个EL自定义函数 --> <function> <description>返回一个字符串的长度</description> <!--函数的功能描述--> <!--EL函数名,也就是在JSP页面中使用时的名称,他可以和java代码中的函数名不一样--> <name>stringLength</name> <!--函数所在的类 --> <function-class>custom.Functions</function-class> <!-- 函数的签名 。函数的返回类型和参数类型强烈建议 给出全名,如:java.lang.String --> <function-signature>java.lang.Integer stringLength(java.lang.String)</function-signature> </function> <function> <description>反转一个字符串</description> <name>reverseString</name> <function-class>custom.Functions</function-class> <function-signature>java.lang.String reverseString(java.lang.String)</function-signature> </function> <!-- 自定义标签tag也是在这个文件中配置的,后面会讲到 --> </taglib>
三、在web.xml中对标签库的位置进行映射(如果将自己的标签库打包为jar文件,则可以像使用JSTL那样方便,无需在web.xml中编写代码)
<!--省略--> <jsp-config> <taglib> <taglib-uri> <!--taglib指令下的uri属性的值--> http://www.nutlee.com/jsp-custom </taglib-uri> <!--tld文件在工程中的位置--> <taglib-location>/WEB-INF/mytag.tld</taglib-location> </taglib> </jsp-config>
四、在JSP文件中使用
<%@taglib uri="http://www.nutlee.com/jsp-custom" prefix="nutlee"%> <!--省略。。。。--> 反转字符串${param.msg}: ${nutlee:reverseString(param.msg)} <br /> 字符串长度${param.msg}: ${nutlee:stringLength(param.msg)} <br /> <!--省略。。。。-->
打包自己的EL函数库为jar文件
如果编写的EL函数经常使用,可以打包为jar文件,这样拷贝到工程的lib下就可以导入使用了。自定义标签库的打包方法也是如此。
步骤:
测试完标签库,确保OK后,右键自定义标签所在的顶层包,【Export】-->【java】下的【JAR file】
然后用解压软件打开jar文件,将先前的tld文件添加到META-INF目录下,这样就OK了。使用时直接放到lib下,让后在JSP中导入。
JSTL中自带的EL函数
导入:
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
${fn:contains(string,substring)}
|
判断字符串string中是否包含子串substring,是则返回true,否则false
|
${fn:containsIgnoreCase(string,substring)}
|
同上,但是忽略大小写
|
${fn:substring(string,beginIndex,endIndex)}
|
返回一个字符串string指定的起始索引的到结束索引(不包含)之间的子串
|
${fn:substringAfter(string,substring)}
|
返回string中第一次出现的substring后面的子字符串
"hello word" , "l" 返回 "lo word"
|
${fn:substringBefore(string,substring )}
|
返回string中第一次出现的substring前面的子字符串
"hello word" , "l" 返回 "he"
|
${fn:endsWith(string,end)}
|
判断字符串string是否以字符串end结尾,是则返回true,否则false
|
${fn:startsWith(string,start)}
|
判断字符串string是否以字符串start开始,是则返回true,否则false
|
${fn:indexOf(string,substring)}
|
返回substring子串在string中第一次出现的索引,如果找不到则返回-1
|
${fn:toUpperCase(string)}
|
返回字符串的大写形式
|
${fn:toLowerCase(string)}
|
返回字符串的小写形式
|
${fn:trim(string)}
|
返回字符串前后的空白符返回
|
${fn:escapeXml(string)}
|
对字符串进行转码
< <
> >
& &
' '
" "
|
${fn:join(stringArray,separatorString)}
|
将String数组中的字符串使用字符串separatorString连接。
返回连接后的字符串
|
${fn:split(string , delimiters)}
|
将字符串string根据指定的分割字符串delimiters来分割成字符串数组返回
|
${fn:length(squence)}
|
返回一个字符串的字符数,或者集合中的元素个数
|
${fn:replace(string, oldStr , newStr )}
|
将字符串string中的所有的oldStr子字符串替换为指定的新的字符串newStr并返回。
|
Apahe的实现源代码
package org.apache.taglibs.standard.functions; import java.lang.reflect.Array; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import javax.servlet.jsp.JspTagException; import org.apache.taglibs.standard.resources.Resources; import org.apache.taglibs.standard.tag.common.core.Util; public class Functions { public static String toUpperCase(String input) { return input.toUpperCase(); } public static String toLowerCase(String input) { return input.toLowerCase(); } public static int indexOf(String input, String substring) { if (input == null) { input = ""; } if (substring == null) { substring = ""; } return input.indexOf(substring); } public static boolean contains(String input, String substring) { return indexOf(input, substring) != -1; } public static boolean containsIgnoreCase(String input, String substring) { if (input == null) { input = ""; } if (substring == null) { substring = ""; } String inputUC = input.toUpperCase(); String substringUC = substring.toUpperCase(); return indexOf(inputUC, substringUC) != -1; } public static boolean startsWith(String input, String substring) { if (input == null) { input = ""; } if (substring == null) { substring = ""; } return input.startsWith(substring); } public static boolean endsWith(String input, String substring) { if (input == null) { input = ""; } if (substring == null) { substring = ""; } int index = input.indexOf(substring); if (index == -1) { return false; } if ((index == 0) && (substring.length() == 0)) { return true; } return index == input.length() - substring.length(); } public static String substring(String input, int beginIndex, int endIndex) { if (input == null) { input = ""; } if (beginIndex >= input.length()) { return ""; } if (beginIndex < 0) { beginIndex = 0; } if ((endIndex < 0) || (endIndex > input.length())) { endIndex = input.length(); } if (endIndex < beginIndex) { return ""; } return input.substring(beginIndex, endIndex); } public static String substringAfter(String input, String substring) { if (input == null) { input = ""; } if (input.length() == 0) { return ""; } if (substring == null) { substring = ""; } if (substring.length() == 0) { return input; } int index = input.indexOf(substring); if (index == -1) { return ""; } return input.substring(index + substring.length()); } public static String substringBefore(String input, String substring) { if (input == null) { input = ""; } if (input.length() == 0) { return ""; } if (substring == null) { substring = ""; } if (substring.length() == 0) { return ""; } int index = input.indexOf(substring); if (index == -1) { return ""; } return input.substring(0, index); } public static String escapeXml(String input) { if (input == null) { return ""; } return Util.escapeXml(input); } public static String trim(String input) { if (input == null) { return ""; } return input.trim(); } public static String replace(String input, String substringBefore, String substringAfter) { if (input == null) { input = ""; } if (input.length() == 0) { return ""; } if (substringBefore == null) { substringBefore = ""; } if (substringBefore.length() == 0) { return input; } StringBuffer buf = new StringBuffer(input.length()); int startIndex = 0; int index; while ((index = input.indexOf(substringBefore, startIndex)) != -1) { buf.append(input.substring(startIndex, index)).append(substringAfter); startIndex = index + substringBefore.length(); } return input.substring(startIndex); } public static String[] split(String input, String delimiters) { if (input == null) { input = ""; } if (input.length() == 0) { String[] array = new String[1]; array[0] = ""; return array; } if (delimiters == null) { delimiters = ""; } StringTokenizer tok = new StringTokenizer(input, delimiters); int count = tok.countTokens(); String[] array = new String[count]; int i = 0; while (tok.hasMoreTokens()) { array[(i++)] = tok.nextToken(); } return array; } public static int length(Object obj) throws JspTagException { if (obj == null) { return 0; } if ((obj instanceof String)) { return ((String)obj).length(); } if ((obj instanceof Collection)) { return ((Collection)obj).size(); } if ((obj instanceof Map)) { return ((Map)obj).size(); } int count = 0; if ((obj instanceof Iterator)) { Iterator iter = (Iterator)obj; count = 0; while (iter.hasNext()) { count++; iter.next(); } return count; } if ((obj instanceof Enumeration)) { Enumeration enum_ = (Enumeration)obj; count = 0; while (enum_.hasMoreElements()) { count++; enum_.nextElement(); } return count; } try { return Array.getLength(obj); } catch (IllegalArgumentException ex) { throw new JspTagException(Resources.getMessage("FOREACH_BAD_ITEMS")); } } public static String join(String[] array, String separator) { if (array == null) { return ""; } if (separator == null) { separator = ""; } StringBuffer buf = new StringBuffer(); for (int i = 0; i < array.length; i++) { buf.append(array[i]); if (i < array.length - 1) { buf.append(separator); } } return buf.toString(); } }