EL函数以及自定义标签的应用
来源:互联网 发布:青铜卡尺 知乎 编辑:程序博客网 时间:2024/06/07 12:40
一、EL函数(调用普通类的静态方法)
编写步骤(自定义EL函数的编写步骤即自定义标签的编写步骤):
①编写一个普通的java类,提供一个静态方法,功能自定,例如下:
package cn.wzbrilliant.el;public class ElFunction { public static String toUpperCase(String str){ return str.toUpperCase(); }}
②在JavaWeb应用的WEB-INF目录下建立一个扩展名是tld(taglib definition)的XML文件。内容如下:
<?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"> <tlib-version>1.0</tlib-version> <short-name>myfn</short-name> <uri>/WEB-INF/myfn.tld</uri> <function><!-- 定义函数 --> <name>toUpper</name> <!-- 调用名称 --> <function-class>cn.wzbrilliant.el.ElFunction</function-class> <!-- 类全名 --> <function-signature>java.lang.String toUpperCase( java.lang.String )</function-signature> </function> </taglib>
<tlib-version>值随意
<short-name>一般与文件名、前缀名称相同,方便查找,不相同也可。
<uri>值随意,只要与web.xml中的uri想对应即可
③(可选步骤)前提是把tld文件放到了WEB-INF目录下。
告知应用,tld文件和tld中的uri的对应。修改web.xml,增加以下内容:
<jsp-config> <taglib> <taglib-uri>/WEB-INF/myfn.tld</taglib-uri> <taglib-location>/WEB-INF/myfn.tld</taglib-location> </taglib></jsp-config>
<taglib> 代表一个标签库,可以多个
<taglib-location> tld文件的位置
④ 在JSP中使用
用taglib指令,引入自定义的EL函数库: <%@ taglib uri="/WEB-INF/myfn.tld" prefix="myfn"%>
使用方式如下:
<% pageContext.setAttribute("p", "abcdef");%>${myfn:toUpper(h) } <br/>${myfn:toUpper("abcdef") }
代码第五行和第六行都可输出"ABCDEF"。
二、EL自定义标签开发
自定义标签属于JSP技术
1、标签的作用
移除掉JSP中的Java脚本(<%%>)
2、编写自定义标签的步骤(自定义EL函数,步骤相同)
自定义标签分为两种,传统标签和简单标签:
这里只介绍简单标签的开发:
①编写一个类,直接或间接实现javax.servlet.jsp.tagext.Tag接口
这里继承SimpleTagSupport类,例子如下:
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class SimpleTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException {// JspFragment jf=getJspBody();// jf.invoke(getJspContext().getOut()); getJspBody().invoke(null); } }
JspFragment对象的invoke方法将标签内容输入到给定的流中,如果为null,例如上面代码,则其作用与注释部分代码相同。
下面以一个获取远程IP地址的代码为例:
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class SimpleTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { PageContext pageContext=(PageContext)getJspContext(); String ip=pageContext.getRequest().getRemoteAddr(); pageContext.getOut().write(ip); } }
<?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"> <tlib-version>1.0</tlib-version> <short-name>mytag</short-name> <uri>/WEB-INF/mytag.tld</uri> <tag><!-- 描述标签 --> <description>Show Remote Address</description> <name>remoteIp</name><!-- 标签名称 --> <tag-class>cn.wzbrilliant.el.SimpleTag</tag-class> <body-content>empty</body-content><!-- 指示标签的主体内容:没有就写empty --> </tag></taglib>
标签内容与EL函数中tld文件中相似。可以添加多个标签。具体如下:
taglib:根元素
tlib-version:版本号
short-name:引用标签时的短名称。一般与tld文件的文件名一致,好找。
uri:标签绑定的名称空间。只是一个名字,没有实际的意义。
tag:定义标签元素
name:标签的名称。
tag-class:标签的实现类的全名称。
body-content:指示标签的主体内容的类型。
可选值:empty:没有主体内容。适用于传统和简单标签。
JSP:说明JSP文件中能出现什么,标签主体内容中就能出现什么。适用于传统标签。
scriptless:说明标签的主体内容不能是java脚本。适用于简单标签。
tagdependent:说明标签的主体内容是原封不动的传递给标签处理类的,而不是传递的运算结果
attribute:定义标签的属性
name:属性名。对应标签处理类中的setter方法
required:是否是必须的属性
rtexprvalue:是否支持表达式(EL或java表达式)。默认是false。
③(可选的)在web.xml中对tld文件和名称空间进行映射对应。
<jsp-config> <taglib> <taglib-uri>/WEB-INF/mytag.tld</taglib-uri> <taglib-location>/WEB-INF/mytag.tld</taglib-location> </taglib></jsp-config>
此处配置与EL函数相同
⑤ 在JSP中使用
首先引入: <%@ taglib uri="/WEB-INF/mytag.tld" prefix="mytag"%>
使用方法:在jsp页面中使用: <mytag:remoteIp /> 即可输出访问服务器的远程的ip地址
3.简单标签的原理:
三、自定义标签实例:
①实现JSTL中forEach标签的功能
类代码如下:
package cn.wzbrilliant.el;import java.io.IOException;import java.lang.reflect.Array;import java.util.ArrayList;import java.util.Collection;import java.util.List;import java.util.Map;import java.util.Set;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class ForEachTag extends SimpleTagSupport { private String var; private Collection items; public void setItems(Object items) { if(items instanceof List){ this.items=(List)items; }else if(items instanceof Set){ this.items=(Set)items; }else if(items instanceof Map){ this.items=((Map)items).entrySet(); }else if(items.getClass().isArray()){ this.items=new ArrayList(); int length=Array.getLength(items); for(int i=0;i<length;i++){ this.items.add(Array.get(items, i)); } }else{ throw new RuntimeException("对不起,不支持的类型"); } } public void setVar(String var) { this.var = var; } @Override public void doTag() throws JspException, IOException { PageContext pageContext=(PageContext) getJspContext(); for(Object obj:items){ pageContext.setAttribute(var, obj); getJspBody().invoke(null); } } }
mytag.tld文件中添加如下内容:
<tag><!-- forEach标签 --> <description>for each</description> <name>forEach</name> <tag-class>cn.wzbrilliant.el.ForEachTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute></tag>
使用方法:
<% int[] arr = new int[] {1,2,3,4}; pageContext.setAttribute("p", arr); %> <mytag:forEach items="${p}" var="v"> ${v}<br> </mytag:forEach>
②实现JSTL中when otherwise功能(与if-else结构相似)
实现用到了父标签。父标签的作用:用于子标签之间数据的传递。
该例使用了三个标签,分别为choose(父标签),when,otherwise,用三个类实现。
父标签choose实现类:
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class ChooseTag extends SimpleTagSupport { private boolean flag=false; protected boolean isFlag(){ return flag; } protected void setFlag(boolean flag){ this.flag=flag; } @Override public void doTag() throws JspException, IOException { getJspBody().invoke(null); } }
子标签when实现类:
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class WhenTag extends SimpleTagSupport { private boolean test; public void setTest(boolean test){ this.test=test; } @Override public void doTag() throws JspException, IOException { if(test){ ChooseTag parent=(ChooseTag)getParent(); parent.setFlag(true); getJspBody().invoke(null); } } }
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class OtherwiseTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { ChooseTag parent=(ChooseTag)getParent(); if(!parent.isFlag()){ getJspBody().invoke(null); } } }
<tag><!-- choose标签 --> <description>when otherwise</description> <name>choose</name> <tag-class>cn.wzbrilliant.el.ChooseTag</tag-class> <body-content>scriptless</body-content></tag> <tag><!-- when标签 --> <description>when otherwise</description> <name>when</name> <tag-class>cn.wzbrilliant.el.WhenTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute></tag> <tag><!-- otherwise标签 --> <description>when otherwise</description> <name>otherwise</name> <tag-class>cn.wzbrilliant.el.OtherwiseTag</tag-class> <body-content>scriptless</body-content></tag>
<% pageContext.setAttribute("p", arr);%> <mytag:choose> <mytag:when test="${empty p }"> there is empty </mytag:when> <mytag:otherwise> <mytag:forEach items="${p }" var="v"> <br>${v} </mytag:forEach> </mytag:otherwise></mytag:choose>
③html显示文本中html代码的过滤
例如留言板中,有时候需要将html代码原样输出,而不解析。
实现类代码如下:
package cn.wzbrilliant.el;import java.io.IOException;import java.io.StringWriter;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class HtmlTextFilterTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { StringWriter sw=new StringWriter(); getJspBody().invoke(sw); String content=sw.toString(); content = filter(content); getJspContext().getOut().write(content); } private String filter(String message) { if (message == null) return (null); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuffer result = new StringBuffer(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); }}
<tag><!-- 文本中Html代码过滤标签 --> <description>htmlfilter</description> <name>htmlfilter</name> <tag-class>cn.wzbrilliant.el.HtmlTextFilterTag</tag-class> <body-content>scriptless</body-content></tag>
使用方式:在jsp页面中输出文本数据时添加此标签便可将文本中html代码原样输出,而不解析。
④防盗链标签
防止别的网站、应用盗链,可以利用EL自定义标签,将请求转向其他URI(自定义的广告等等)
实现代码如下:
package cn.wzbrilliant.el;import java.io.IOException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class RefererTag extends SimpleTagSupport { private String site; private String redirectPath; public void setSite(String site) { this.site = site; } public void setRedirectPath(String redirectPath) { this.redirectPath = redirectPath; } @Override public void doTag() throws JspException, IOException { PageContext pageContext = (PageContext) getJspContext(); HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); HttpServletResponse response = (HttpServletResponse) pageContext.getResponse(); String referer = request.getHeader("referer"); if (referer != null && !referer.startsWith(site)) { String path; if (redirectPath.startsWith("/")) { path = request.getContextPath() + redirectPath; } else { String uri=request.getRequestURI(); path=uri.substring(0, uri.lastIndexOf("/")+1)+redirectPath; } response.sendRedirect(path); } }}
mytag.tld中添加如下内容:
<tag><!-- 防盗链 --> <description>referer</description> <name>referer</name> <tag-class>cn.wzbrilliant.el.RefererTag</tag-class> <body-content>empty</body-content> <attribute> <name>site</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>redirectPath</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute></tag>
四、JSTL中的核心标签库(替换掉JSP中的Java脚本)
① c:if
作用:判断是否为true,如果为true,那么标签的主体内容就会显示。
属性:test:必须的。要求必须是boolean的。支持表达式(EL或Java表达式)
var:保存test运算结果的变量
scope: 保存的域范围。默认是page
②c:forEach
遍历:数组、List、Set、Map
属性:items:要遍历的目标对象。支持表达式
var:变量名。指向当前遍历的集合中的一个元素
begin:开始的索引(含)
end:结束的索引(含)
step:步长。默认是1
varStatus:取一个名字,引用了一个对象。该对象有以下方法:
int getIndex():当前记录的索引号。从0开始
int getCount():当前记录的顺序。从1开始
boolean isFirst():是否是第一条记录
boolean isLast():是否是最后一条记录
博客园博客:欠扁的小篮子
- EL函数以及自定义标签的应用
- 【自定义标签】EL函数
- El表达式 自定义标签 El函数区别
- 自定义标签&JSTL标签库&EL函数
- JavaWeb 自定义标签&EL自定义函数
- jsp自定义标签tag EL函数
- 自定义EL表达式的函数
- 自定义EL函数的使用
- 自定义EL函数的步骤
- java程序员第十三课-EL表达式、JSTL标签库、EL函数库、自定义EL函数和自定义标签
- 自定义EL标签
- el表达式和jstl标签的应用
- el表达式和jstl标签的应用
- 自定义标签的应用
- JAVAWEB开发之JSTL标签库的使用、 自定义EL函数、自定义标签(带属性的、带标签体的)
- JAVAWEB开发之JSTL标签库的使用、 自定义EL函数、自定义标签(带属性的、带标签体的)
- 实际项目开发中需要的格式化标签以及JSTL标签库介绍【1核心标签(用得最多)2 国际化标签(I18N格式化标签) 数据库标签(SQL标签,很少使用) XML标签(几乎不用) JSTL函数(EL函数)】
- EL调用普通类的静态方法(EL自定义函数)
- 高仿煎蛋iOS项目基础配置(2)
- Interlocked(续)
- Apache源码分析
- 深入理解OAuth2.0协议
- 简述UIView、UIWindow和CALayer的理解
- EL函数以及自定义标签的应用
- Unix整理笔记——Unix基础——里程碑
- 第五章:循环
- 三分钟理解“享元模式”——设计模式轻松掌握
- Android JNI打印Log
- Sql 调优 与 OLPT
- spring 拦截器(ProxyFactoryBean,BeanNameAutoProxyCreator)
- iOS-数据持久化(一)
- 【软工6】软件开发小组