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

一、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);
    }

}

②在WEB-INF目录下建立一个扩展名为tld(Tag
Libary 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>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);
        }
    }

}

子标签otherwise实现类:

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);
        }
    }

}

mytag.tld中添加如下内容:

<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>

使用方法,在jsp中:

<%
    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());
    }
}

mytag.tld中添加如下内容:

<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>

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

博客园博客:欠扁的小篮子

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 11:55:55

EL函数以及自定义标签的应用的相关文章

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函数.必须在工程的c

EL表达式 JSTL的标签库 EL的函数 自定义EL函数 自定义标签 JSP的开发模式 注册登陆案例

EL表达式 JSTL的标签库 EL的函数 自定义EL函数 自定义标签 JSP的开发模式 注册登陆案例 EL表达式 1.获取域对象中的值 2.EL表达式支持运算 ${ num1 + num2 } EL获取常用的WEB对象 1.pageScope 获取page域对象的值 2.requestScope 获取request域对象的值 3.sessionScope 获取session域对象的值 4.applicationScope 获取application域对象的值 * 例子:向某个域中来存入值 req

jsp自定义标签tag EL函数

原文:jsp自定义标签tagEL函数 源代码下载地址:http://www.zuidaima.com/share/1550463459052544.htm 简单易懂的自定义EL函数 tag.java </pre><p> </p><pre name="code" class="java">package com.zuidaima.tag; import java.io.IOException; import javax.

自定义el函数

1.1.1 自定义EL函数(EL调用Java的函数) 第一步:创建一个Java类.方法必须是静态方法. public static String sayHello(String name){ return "Hello " + name; } 第二步:提供一个tld文件.(tld文件标签库文件.放置在WEB-INF 下) 在tld文件中定义: <!-- 自定义EL函数 --> <function> <!-- 函数名 --> <name>s

Javaweb学习笔记6—EL表达式与JSTL及自定义标签

 前几天博客被黑了,导致博客登陆不上,把前几天应该发的东西的东西重新发一遍 今天来讲javaweb的第六阶段学习. EL表达式与JSTL及自定义标签是对上篇文章介绍的JSP的扩展,不能说是很重要的东西,但是也要了解. 老规矩,首先先用一张思维导图来展现今天的博客内容. ps:我的思维是用的xMind画的,如果你对我的思维导图感兴趣并且想看到你们跟详细的备注信息,请点击下载 另外:如果图看不清的话请右击---在新窗口中打开会清楚很多. 一.EL表达式 1,EL简介 Expression Lan

JavaWeb学习之JSTL自定义标签库的使用、JSTL自定义函数库(7)

一.自定义标签,步骤 * 确定需求 * <my:date /> 输出当前系统的时间 yyyy-MM-dd hh:mm:ss:SSS * 编写Java类 新建包名:com.yxl.tag,新建类MyDateTag,实现SimpleTag接口 * 只要与此接口有关的实现类,javax.servlet.jsp.tagext.JspTag * 需要实现具体的接口 * javax.servlet.jsp.tagext.SimpleTag,简单标签,JSP2.0**,选择这个 * javax.servle

自定义一个EL函数

自定义一个EL函数 一般就是一下几个步骤,顺便提供一个工作常用的 案例: 1.编写一个java类,并编写一个静态方法(必需是静态方法),如下所示: public class DateTag { private final static Logger logger = LogManager.getLogger(DateTag.class); private static final long serialVersionUID = -2312310581852395045L; public stat

18、EL表达式、JSP标签、JSTL标签、自定义标签

EL表达式 jsp的核心语法: jsp表达式 <%=%>和 jsp脚本<% %>. 以后开发jsp的原则: 尽量在jsp页面中少写甚至不写java代码. 使用EL表达式替换掉jsp表达式 EL表达式作用: 向浏览器输出域对象中的变量值或表达式计算的结果!!! 语法: ${变量或表达式} EL语法 1 输出基本数据类型变量 从四个域获取 ${name} 指定域获取 ${pageScope.name} 域范围: pageScoep / requestScope / sessionSco

Jsp2.0自定义标签(第三天)——EL表达式的使用

1.提出问题: 我们经常会看到这样的jsp页面代码: 浏览器显示: 为什么会在页面输出:Hello World  ,${per}究竟是如何找到“Hello World”的呢? 2.分析问题: 要想解决上述疑问,首先要试试自己能不能自定义出上面的标签. 比如我想定义<myout:demo print="${per}"/>拥有打印出EL表达式值的功能. 同前面几章一样,自定义标签我分为几个部分: 第一部分:定义标签的地方(*.tld). <?xml version=&qu