博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EL函数以及自定义标签的应用
阅读量:6853 次
发布时间:2019-06-26

本文共 13006 字,大约阅读时间需要 43 分钟。

一、EL函数(调用普通类的静态方法)

编写步骤(自定义EL函数的编写步骤即自定义标签的编写步骤):

 

①编写一个普通的java类,提供一个静态方法,功能自定,例如下:

1 package cn.wzbrilliant.el;2 3 public class ElFunction {4     public static String toUpperCase(String str){5         return str.toUpperCase();6     }7 }

 

②在JavaWeb应用的WEB-INF目录下建立一个扩展名是tld(taglib definition)的XML文件。内容如下:

1 
2
5
1.0
6
myfn
7
/WEB-INF/myfn.tld
8 9
10
toUpper
11
cn.wzbrilliant.el.ElFunction
12
java.lang.String toUpperCase( java.lang.String )
13
14 15

<tlib-version>值随意

<short-name>一般与文件名、前缀名称相同,方便查找,不相同也可。

<uri>值随意,只要与web.xml中的uri想对应即可

③(可选步骤)前提是把tld文件放到了WEB-INF目录下。
告知应用,tld文件和tld中的uri的对应。修改web.xml,增加以下内容:

1 
2
3
/WEB-INF/myfn.tld
4
/WEB-INF/myfn.tld
5
6

<taglib> 代表一个标签库,可以多个

<taglib-location> tld文件的位置

 

④ 在JSP中使用

用taglib指令,引入自定义的EL函数库: <%@ taglib uri="/WEB-INF/myfn.tld" prefix="myfn"%> 

使用方式如下:

1 <%2         pageContext.setAttribute("p", "abcdef");3 %>4 5 ${myfn:toUpper(h) } 
6 ${myfn:toUpper("abcdef") }

代码第五行和第六行都可输出"ABCDEF"。

 

二、EL自定义标签开发

 

自定义标签属于JSP技术

 

1、标签的作用

移除掉JSP中的Java脚本(<%%>)

 

2、编写自定义标签的步骤(自定义EL函数,步骤相同)

 

自定义标签分为两种,传统标签简单标签

 

 

这里只介绍简单标签的开发:

 

①编写一个类,直接或间接实现javax.servlet.jsp.tagext.Tag接口

 

这里继承SimpleTagSupport类,例子如下: 

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7  8 public class SimpleTag extends SimpleTagSupport { 9 10     @Override11     public void doTag() throws JspException, IOException {12 //        JspFragment jf=getJspBody();13 //        jf.invoke(getJspContext().getOut());14         15         getJspBody().invoke(null);16         17     }18     19 }

 

 

JspFragment对象的invoke方法将标签内容输入到给定的流中,如果为null,例如上面代码,则其作用与注释部分代码相同。

下面以一个获取远程IP地址的代码为例:

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.PageContext; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8  9 public class SimpleTag extends SimpleTagSupport {10 11     @Override12     public void doTag() throws JspException, IOException {13         PageContext pageContext=(PageContext)getJspContext();14         String ip=pageContext.getRequest().getRemoteAddr();15         pageContext.getOut().write(ip);16     }17     18 }

 

在WEB-INF目录下建立一个扩展名为tld(Tag Libary Definition)的xml文件。

1 
2
5 6
1.0
7
mytag
8
/WEB-INF/mytag.tld
9 10
11
Show Remote Address
12
remoteIp
13
cn.wzbrilliant.el.SimpleTag
14
empty
15
16 17

标签内容与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文件和名称空间进行映射对应。

1 
2
3
/WEB-INF/mytag.tld
4
/WEB-INF/mytag.tld
5
6

此处配置与EL函数相同

 

⑤ 在JSP中使用

首先引入: <%@ taglib uri="/WEB-INF/mytag.tld" prefix="mytag"%> 

使用方法:在jsp页面中使用: <mytag:remoteIp />  即可输出访问服务器的远程的ip地址

 

3.简单标签的原理:

 

三、自定义标签实例:

 

①实现JSTL中forEach标签的功能

类代码如下:

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4 import java.lang.reflect.Array; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 import java.util.List; 8 import java.util.Map; 9 import java.util.Set;10 11 import javax.servlet.jsp.JspException;12 import javax.servlet.jsp.PageContext;13 import javax.servlet.jsp.tagext.SimpleTagSupport;14 15 public class ForEachTag extends SimpleTagSupport {16     private String var;17     private Collection items;18     19     public void setItems(Object items) {20         if(items instanceof List){21             this.items=(List)items;22         }else if(items instanceof Set){23             this.items=(Set)items;24         }else if(items instanceof Map){25             this.items=((Map)items).entrySet();26         }else if(items.getClass().isArray()){27             this.items=new ArrayList();28             int length=Array.getLength(items);29             for(int i=0;i

 

mytag.tld文件中添加如下内容:

1 
2
for each
3
forEach
4
cn.wzbrilliant.el.ForEachTag
5
scriptless
6
7
items
8
true
9
true
10
11
12
var
13
true
14
true
15
16

 

使用方法:

1  <%2     int[] arr = new int[] {1,2,3,4};3 4     pageContext.setAttribute("p", arr);5  %>6         7  
8 ${v}
9

与JSTL中forEach标签使用无异,如此便可遍历数组、集合的元素。

 

 

②实现JSTL中when  otherwise功能(与if-else结构相似)

 

实现用到了父标签。父标签的作用:用于子标签之间数据的传递。

该例使用了三个标签,分别为choose(父标签),when,otherwise,用三个类实现。

父标签choose实现类:

 

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7  8 public class ChooseTag extends SimpleTagSupport { 9     private boolean flag=false;10     11     protected boolean isFlag(){12         return flag;13     }14     15     protected void setFlag(boolean flag){16         this.flag=flag;17     }18 19     @Override20     public void doTag() throws JspException, IOException {21 22         getJspBody().invoke(null);23     }24     25     26 }

 

 

子标签when实现类:

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7  8 public class WhenTag extends SimpleTagSupport { 9     private boolean test;10     11     public void setTest(boolean test){12         this.test=test;13     }14 15     @Override16     public void doTag() throws JspException, IOException {17         if(test){18             ChooseTag parent=(ChooseTag)getParent();19             parent.setFlag(true);20             getJspBody().invoke(null);21         }22     }23     24     25 }

 

子标签otherwise实现类:

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.jsp.JspException; 6 import javax.servlet.jsp.tagext.SimpleTagSupport; 7  8 public class OtherwiseTag extends SimpleTagSupport { 9 10     @Override11     public void doTag() throws JspException, IOException {12         ChooseTag parent=(ChooseTag)getParent();13         if(!parent.isFlag()){14             getJspBody().invoke(null);15         }16     }17     18 }

 

mytag.tld中添加如下内容:

1 
2
when otherwise
3
choose
4
cn.wzbrilliant.el.ChooseTag
5
scriptless
6
7 8
9
when otherwise
10
when
11
cn.wzbrilliant.el.WhenTag
12
scriptless
13
14
test
15
true
16
true
17
18
19 20
21
when otherwise
22
otherwise
23
cn.wzbrilliant.el.OtherwiseTag
24
scriptless
25

 

使用方法,在jsp中:

1 <% 2     pageContext.setAttribute("p", arr); 3 %> 4  5          6 
7
8 there is empty 9
10
11
12
${v}13
14
15

 

 

html显示文本中html代码的过滤 

 

例如留言板中,有时候需要将html代码原样输出,而不解析。

实现类代码如下:

 

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4 import java.io.StringWriter; 5  6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.tagext.SimpleTagSupport; 8  9 public class HtmlTextFilterTag extends SimpleTagSupport {10 11     @Override12     public void doTag() throws JspException, IOException {13         StringWriter sw=new StringWriter();14         getJspBody().invoke(sw);15         String content=sw.toString();16         content = filter(content);17         getJspContext().getOut().write(content);18     }19 20     private String filter(String message) {21         if (message == null)22             return (null);23 24         char content[] = new char[message.length()];25         message.getChars(0, message.length(), content, 0);26         StringBuffer result = new StringBuffer(content.length + 50);27         for (int i = 0; i < content.length; i++) {28             switch (content[i]) {29             case '<':30                 result.append("<");31                 break;32             case '>':33                 result.append(">");34                 break;35             case '&':36                 result.append("&");37                 break;38             case '"':39                 result.append(""");40                 break;41             default:42                 result.append(content[i]);43             }44         }45         return (result.toString());46     }47 }

 

 

mytag.tld中添加如下内容:

1 
2
htmlfilter
3
htmlfilter
4
cn.wzbrilliant.el.HtmlTextFilterTag
5
scriptless
6

 

使用方式:在jsp页面中输出文本数据时添加此标签便可将文本中html代码原样输出,而不解析。

 

④防盗链标签

防止别的网站、应用盗链,可以利用EL自定义标签,将请求转向其他URI(自定义的广告等等)

实现代码如下:

 

1 package cn.wzbrilliant.el; 2  3 import java.io.IOException; 4  5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.http.HttpServletResponse; 7 import javax.servlet.jsp.JspException; 8 import javax.servlet.jsp.PageContext; 9 import javax.servlet.jsp.tagext.SimpleTagSupport;10 11 public class RefererTag extends SimpleTagSupport {12     private String site;13     private String redirectPath;14 15     public void setSite(String site) {16         this.site = site;17     }18 19     public void setRedirectPath(String redirectPath) {20         this.redirectPath = redirectPath;21     }22 23     @Override24     public void doTag() throws JspException, IOException {25         PageContext pageContext = (PageContext) getJspContext();26         HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();27         HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();28         String referer = request.getHeader("referer");29         if (referer != null && !referer.startsWith(site)) {30             String path;31             if (redirectPath.startsWith("/")) {32                 path = request.getContextPath() + redirectPath;33             } else {34                 String uri=request.getRequestURI();35                 path=uri.substring(0, uri.lastIndexOf("/")+1)+redirectPath;36             }37             response.sendRedirect(path);38         }39     }40 41 }

 

 

mytag.tld中添加如下内容:

1 
2
referer
3
referer
4
cn.wzbrilliant.el.RefererTag
5
empty
6
7
site
8
true
9
true
10
11
12
redirectPath
13
true
14
true
15
16

 

使用方法:在防盗链的页面头部添加: <mytag:referer site="http://localhost:8080/JavaWeb" redirectPath="error.jsp"/> ,其中site值为本应用的URI,redirectPath是将外部应用的请求转发的目标地址,可以是相对路径,也可以是绝对路径。

 

四、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():是否是最后一条记录

转载于:https://www.cnblogs.com/z941030/p/4767712.html

你可能感兴趣的文章
测试并发应用(二)监控Phaser类
查看>>
云上游戏数据分析实践
查看>>
前端如何实现数据双向绑定
查看>>
视频码率那些事
查看>>
Android仿网易云音乐:留声机效果
查看>>
vue-cli项目升级webpack4踩坑
查看>>
Python爬虫框架,内置微博、自如、豆瓣图书、拉勾、拼多多等规则
查看>>
android View 的绘制流程
查看>>
怎么实现mybatis半自动化解耦!看看资深程序员怎么说
查看>>
一个能拖动,能调整大小,能更新bind值的vue指令-vuedragx
查看>>
记一次基于vue-cli的多页面应用配置
查看>>
适用于小程序的 ES6
查看>>
Ribbon使用方法
查看>>
【译】将 Android 项目迁移到 Kotlin 语言
查看>>
vue 项目打包部署,通过nginx 解决跨域问题
查看>>
LightKV-高性能key-value存储组件
查看>>
小程序
查看>>
ES6变量的解构赋值
查看>>
ansible自动化运维详细教程及playbook详解
查看>>
快速解决Dev c++无法调试
查看>>