简介

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)}
对字符串进行转码
 
<        &lt;
>        &gt;
&        &amp;
'         &apos;
"        &quot;
${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函数的更多相关文章

  1. 【JSP】EL函数和自定义EL函数

    简介 EL原本是JSTL1.0中的技术(所以EL和JSTL感情如此好就是自然的了),但是从JSP2.0开始,EL就分离出来纳入了JSP的标准了.但是EL函数还是和JSTL技术绑定在一起.下面将介绍如何 ...

  2. ptyhon 编程基础之函数篇(二)-----返回函数,自定义排序函数,闭包,匿名函数

    一.自定义排序函数 在Python中可以使用内置函数sorted(list)进行排序: 结果如下图所示: 但sorted也是一个高阶函数,可以接受两个参数来实现自定义排序函数,第一个参数为要排序的集合 ...

  3. QT+信号和槽函数_自定义槽函数_一个信号对应多个槽函数

    以下的代码里面有自定义槽函数的内容,同时也有信号实现的函数: #ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #i ...

  4. 用于调试的printf函数和自定义log函数

    1. 用宏定义调试用的DPRINT #define DEBUG_ENABLE #ifdef DEBUG_ENABLE #define DPRINT(fmt, args...) fprintf(stde ...

  5. EntityFramework Core 2.0自定义标量函数两种方式

    前言 上一节我们讲完原始查询如何防止SQL注入问题同时并提供了几种方式.本节我们继续来讲讲EF Core 2.0中的新特性自定义标量函数. 自定义标量函数两种方式 在EF Core 2.0中我们可以将 ...

  6. Python 函数进阶-高阶函数

    高阶函数 什么是高阶函数 高阶函数就是能够把函数当成参数传递的函数就是高阶函数,换句话说如果一个函数的参数是函数,那么这个函数就是一个高阶函数. 高阶函数可以是你使用def关键字自定义的函数,也有Py ...

  7. 自定义el函数

    1.1.1 自定义EL函数(EL调用Java的函数) 第一步:创建一个Java类.方法必须是静态方法. public static String sayHello(String name){ retu ...

  8. EL函数以及自定义标签的应用

    一.EL函数(调用普通类的静态方法) 编写步骤(自定义EL函数的编写步骤即自定义标签的编写步骤): ①编写一个普通的java类,提供一个静态方法,功能自定,例如下: package cn.wzbril ...

  9. [原创]java WEB学习笔记42:带标签体的自定义标签,带父标签的自定义标签,el中自定义函数,自定义标签的小结

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

随机推荐

  1. 如何用VS进行程序调试

    VS是一个强大的IDE,如果你现在只会简单地用它查看一下执行效果,那就太大材小用了. 1. CRT函数报错 首先来说说最常见的一个编译错误.微信里常常收到这个错误的截图提问. CRT(C Runtim ...

  2. [附录]Discuz X2.5 模板目录结构注释说明

    /template/default/common  公共模板目录全局加载 block_forumtree.htm  DIY论坛树形列表模块 block_thread.htm  DIY帖子模块调用文件 ...

  3. iOS工程师常用的命令行命令总结

    感觉有点标题党了. 作为一个iOS工程师,没有做过服务端,主要用的是mac电脑,此篇博文是记录我在工作,学习的过程中用的命令行命令的记录和归纳总结 一. mac命令行 1. cd /Users/xxx ...

  4. js脚本都可以放在哪些地方

    js脚本应该放在页面的什么地方 1.head部分 包含函数的脚本位于文档的 head 部分.这样我们就可以确保在调用函数前,脚本已经载入了. 2.body部分 执行位于 body 部分的脚本. 3.外 ...

  5. 写JS自执行函数时要注意的

    JS是非强类型语言,且IDE也不够智能,所以经常会在语句结束时漏写了分号,一般情况下这是不影响运行的, 但如果后面跟上的是一段自执行的函数,就会报出 "..... is not functi ...

  6. Webpack 资源管理

    Webpack 资源管理

  7. CenOS http 安装与运行

    1.yum安装http [root@localhost ~]# yum install httpd -y 2.启动http服务 [root@localhost ~]# systemctl start  ...

  8. 题解 最优的挤奶方案(Optimal Milking)

    最优的挤奶方案(Optimal Milking) 时间限制: 1 Sec  内存限制: 128 MB 题目描述 农场主 John 将他的 K(1≤K≤30)个挤奶器运到牧场,在那里有 C(1≤C≤20 ...

  9. MYSQL数据类型和where条件判断

    MySQL中常见的数据类型 一.字符型 ① CHAR(N):固定N个字符长度的字符串,如果长度不够自动空格补齐; N的范围 0~255 ② VARCHAR(N): 存储可变长度的字符串,最常用 ③ T ...

  10. Mac: 易用设置

    Mac是一个类unix系统,因此很多命令是类似于Linux的.例如其中的Terminal, shell等等.但是软件源鉴于国内的网络环境,是不方便配置的. 中文输入法快速切换. 在不同的语言中可以用组 ...