EL函数和自定义EL函数
简介
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中被识别。
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();
}
}
EL函数和自定义EL函数的更多相关文章
- 【JSP】EL函数和自定义EL函数
简介 EL原本是JSTL1.0中的技术(所以EL和JSTL感情如此好就是自然的了),但是从JSP2.0开始,EL就分离出来纳入了JSP的标准了.但是EL函数还是和JSTL技术绑定在一起.下面将介绍如何 ...
- ptyhon 编程基础之函数篇(二)-----返回函数,自定义排序函数,闭包,匿名函数
一.自定义排序函数 在Python中可以使用内置函数sorted(list)进行排序: 结果如下图所示: 但sorted也是一个高阶函数,可以接受两个参数来实现自定义排序函数,第一个参数为要排序的集合 ...
- QT+信号和槽函数_自定义槽函数_一个信号对应多个槽函数
以下的代码里面有自定义槽函数的内容,同时也有信号实现的函数: #ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #i ...
- 用于调试的printf函数和自定义log函数
1. 用宏定义调试用的DPRINT #define DEBUG_ENABLE #ifdef DEBUG_ENABLE #define DPRINT(fmt, args...) fprintf(stde ...
- EntityFramework Core 2.0自定义标量函数两种方式
前言 上一节我们讲完原始查询如何防止SQL注入问题同时并提供了几种方式.本节我们继续来讲讲EF Core 2.0中的新特性自定义标量函数. 自定义标量函数两种方式 在EF Core 2.0中我们可以将 ...
- Python 函数进阶-高阶函数
高阶函数 什么是高阶函数 高阶函数就是能够把函数当成参数传递的函数就是高阶函数,换句话说如果一个函数的参数是函数,那么这个函数就是一个高阶函数. 高阶函数可以是你使用def关键字自定义的函数,也有Py ...
- 自定义el函数
1.1.1 自定义EL函数(EL调用Java的函数) 第一步:创建一个Java类.方法必须是静态方法. public static String sayHello(String name){ retu ...
- EL函数以及自定义标签的应用
一.EL函数(调用普通类的静态方法) 编写步骤(自定义EL函数的编写步骤即自定义标签的编写步骤): ①编写一个普通的java类,提供一个静态方法,功能自定,例如下: package cn.wzbril ...
- [原创]java WEB学习笔记42:带标签体的自定义标签,带父标签的自定义标签,el中自定义函数,自定义标签的小结
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- (转)微信禁用右上角的分享按钮,WeixinJSBridge API以及隐藏分享的子按钮等菜单项
<!--禁用微信分享按钮--> <script> function onBridgeReady() { WeixinJSBridge.call('hideOptionMenu' ...
- Java基础——继承
学习Java继承之前,我们想回忆一下Java面向对象需要特别注意的几个关键点. 面向对象是将复杂的事情简单化了,它通过封装的方式使得代码的重用性更高和安全性更强.平时我们要学会用面向对象的方式去思考, ...
- node.js零基础详细教程(7):node.js操作mongodb,及操作方法的封装
第七章 建议学习时间4小时 课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑. ...
- AngularJS高级程序设计读书笔记 -- 服务篇
服务是提供在整个应用程序中所使用的任何功能的单例对象. 单例 : 只用一个对象实例会被 AngularJS 创建出来, 并被程序需要服务的各个不同部分所共享. 1. 内置服务 一些关键方法也被 Ang ...
- fpm 制作 rpm 包
支持的 源类型包 ① dir : 将目录打包成所需要的类型, 可用于源码编译安装软件包 ② rpm : 对 rpm 包进行转换 ③ gem : 对 rubygem 包进行转换 ④ python : 将 ...
- 基于FPGA的IIR滤波器
基于FPGA的IIR滤波器 by方阳 版权声明:本文为博主原创文章,转载请指明转载地址 ...
- Linux网络编程“惊群”问题总结
1.前言 我从事Linux系统下网络开发将近4年了,经常还是遇到一些问题,只是知其然而不知其所以然,有时候和其他人交流,搞得非常尴尬.如今计算机都是多核了,网络编程框架也逐步丰富多了,我所知道的有多进 ...
- Linux 开机引导流程
Linux 开机启动流程 BIOS(Basic Input Output System)是 PC 机启动时加载的第一个软件.其实,它是一组固化到计算机主板上一个芯片上的程序,它保存着计算机最重要的输入 ...
- 用 Docker Machine 创建 Azure 虚拟主机
搭建环境向来是一个重复造轮子的过程,Docker Machine 则把用户搭建 Docker 环境的各种方案汇集在了一起.笔者在<Docker Machine 简介>一文中演示了使用 Do ...
- 将百度坐标转换的javascript api官方示例改写成传统的回调函数形式
改写前: 百度地图中坐标转换的JavaScript API示例官方示例如下: var points = [new BMap.Point(116.3786889372559,39.90762965106 ...
.png)