简介

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. asp.net MVC 网站图片防盗链的几种方法

    目录 1. 通过 URL Rewrite Module 组件 2. 通过 nginx 图片防盗链 3.自定义 HttpHandler 处理 4. 通过 MVC 自定义路由规则防盗链 5. 通过 MVC ...

  2. 初识Tensorboard

    1.什么是Tensorboard? PPT设计原则中有这样一条,叫"文不如表,表不如图",可见图表在表达中更为直观.明确.程序设计中也是一样,我们经常用图表来描述程序的结构和流程, ...

  3. Pycon 2017: Python可视化库大全

    本文首发于微信公众号“Python数据之道” 前言 本文主要摘录自 pycon 2017大会的一个演讲,同时结合自己的一些理解. pycon 2017的相关演讲主题是“The Python Visua ...

  4. HTML/XML/XPATH基础

    Html超文本标记语言 网页上单击右键→查看源文件/查看源代码 Html基本结构 <html>               为文档根元素,所有元素都在内部进行 <head>   ...

  5. Chapter 1:Introduction

    作者:桂. 时间:2017-05-24  08:06:45 主要是<Speech enhancement: theory and practice>的读书笔记,全部内容可以点击这里. 1. ...

  6. Angularjs1.2版本与1.3版本中控制器的问题

    写写今天用ng遇到的一个问题吧.因为刚学习就学视频里面写例子,视频里用的是ng1.2.10版本,我用的是1.5.0. 刚开始的时候我按照ng视频的里面的写,但是控制器就是不能绑定好,后来和同学讨论加搜 ...

  7. [转]TOMCAT配置多端口

    一.Tomcat 安装后本身提供了一个server,端口配置默认是8080,对应目录为:..\Tomcat 6.0\webapps二.Tomcat 6.0 配置多个端口,其实也就是给Tomcat增加几 ...

  8. Navicat连接报错:cannot load OCI DLL,126

    32位系统下报错:cannot load OCI DLL,126 解决方法:navicat 菜单中 -工具->选项->OCI 选择oracle安装目录下bin里面的oci.dll 在win ...

  9. thinkphp中fetch渲染模板的处理

    <script type="text/javascript"> function xiugai(elm){ var formData1=$("#a1_&quo ...

  10. [leetcode-474-Ones and Zeroes]

    In the computer world, use restricted resource you have to generate maximum benefit is what we alway ...