zoukankan      html  css  js  c++  java
  • JSP第四篇【EL表达式介绍、获取各类数据、11个内置对象、执行运算、回显数据、自定义函数、fn方法库】

    什么是EL表达式?#

    表达式语言(Expression Language,EL),EL表达式是用"${}"括起来的脚本,用来更方便的读取对象!

    • EL表达式主要用来读取数据,进行内容的显示!

    为什么要使用EL表达式?

    • 为什么要使用EL表达式,我们先来看一下没有EL表达式是怎么样读取对象数据的吧

    • 在1.jsp中设置了Session属性

    
    <%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%>
    <html>
    <head>
        <title>向session设置一个属性</title>
    </head>
    <body>
    
    <%
        //向session设置一个属性
        session.setAttribute("name", "aaa");
        System.out.println("向session设置了一个属性");
    %>
    
    </body>
    </html>
    
    
    • 在2.jsp中获取Session设置的属性
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    
    <%
            String value = (String) session.getAttribute("name");
            out.write(value);
    %>
    </body>
    </html>
    
    
    
    • 效果:

    • 上面看起来,也没有多复杂呀,那我们试试EL表达式的!

    • 在2.jsp中读取Session设置的属性

    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title></title>
    </head>
    <body>
    
    ${name}
    
    </body>
    </html>
    
    
    
    • 只用了简简单单的几个字母就能输出Session设置的属性了!并且输出在浏览器上!

    • 使用EL表达式可以方便地读取对象中的属性、提交的参数、JavaBean、甚至集合

    EL表达式的作用

    • 首先来看一下EL表达式的语法吧
    
    ${标识符}
    
    
    • EL表达式如果找不到相应的对象属性,返回的的空白字符串“”,而不是null,这是EL表达式最大的特点!

    获取各类数据

    获取域对象的数据

    • 上面在例子中,我们已经体验到了获取Session域对象的数据是多么地方便!其实EL表达式可以让我们获取各个域范围的数据
    • 在1.jsp中设置ServeltContext属性(也就是application)
    
    <%
        //向ServletContext设置一个属性
        application.setAttribute("name", "aaa");
        System.out.println("向application设置了一个属性");
    %>
    
    
    • 在2.jsp中获取application的属性
    
    
    <%
        ${name}
    
    %>
    
    
    
    • 和Session一样,也能获取得到!

    • 之前我们来讲ServletContext对象的时候讲过一个方法findAttribute(String name),EL表达式语句在执行的时候会调用该方法,用标识符作为关键字分别从page、request、session、application四个域中查找相应的对象。这也解释了为什么EL表达式可以仅仅通过标识符就能够获取到存进域对象的数据!
    • findAttribute()的查找顺序:从小到大,也就是page->request->session->application

    获取JavaBean的属性

    • 以前在JSP页面获取JavaBean的数据是这样子的
    • 1.jsp页面Session存进一个Person对象,设置age的属性为22
    
    	<jsp:useBean id="person" class="domain.Person" scope="session"/>
    	<jsp:setProperty name="person" property="age" value="22"/>
    
    

    在2.jsp中取出Session的属性

    
    <%
    
        Person person = (Person) session.getAttribute("person");
    
        System.out.println(person.getAge());
    %>
    
    
    • 效果如下

    • 现在我使用了EL表达式读取数据又会非常方便了
    
    	//等同于person.getAge()
    	${person.age}
    
    
    

    • 上面的代码 等同于调用对象的getter方法,内部是通过反射机制完成的

    获取集合的数据

    • 集合操作在开发中被广泛地采用,在EL表达式中也很好地支持了集合的操作!可以非常方便地读取Collection和Map集合的内容

    • 为了更好地看出EL表达式的强大之处,我们也来对比一下使用EL表达式和不使用EL表达式的区别

    • 下面不使用EL表达式输出集合的元素

    • 在1.jsp页面中设置session的属性,session属性的值是List集合,List集合装载的又是Person对象

    
    	<%
    	    List<Person> list = new ArrayList();
    	
    	    Person person1 = new Person();
    	    person1.setUsername("zhongfucheng");
    	
    	    Person person2 = new Person();
    	    person2.setUsername("ouzicheng");
    	
    	    list.add(person1);
    	    list.add(person2);
    	
    	    session.setAttribute("list",list);
    	%>
    
    
    • 在2.jsp中获取到session的属性,并输出到页面上
    	<%
    	
    	    List<Person> list = (List) session.getAttribute("list");
    	
    	    out.write(list.get(0).getUsername()+"<br>");
    	
    	    out.write(list.get(1).getUsername());
    	
    	%>
    
    

    使用EL表达式又是怎么样的效果呢?我们来看看

    <%--取出list集合的第1个元素(下标从0开始),获取username属性--%>
    ${list[0].username}
    <br>
    <%--取出list集合的第2个元素,获取username属性--%>
    ${list[1].username}
    
    
    
    • 同样也可以有相同的效果:

    • 我们再来使用一下Map集合

    • 在1.jsp中session属性存储了Map集合,Map集合的关键字是字符串,值是Person对象

    
    <%
    
        Map<String, Person> map = new HashMap<>();
    
        Person person1 = new Person();
        person1.setUsername("zhongfucheng1");
    
        Person person2 = new Person();
        person2.setUsername("ouzicheng1");
    
        map.put("aa",person1);
        map.put("bb",person2);
    
        session.setAttribute("map",map);
    %>
    
    
    • 看起来好像取出数据的时候是会有点复杂,但是有了EL表达式也是非常轻松的
    
    ${map.aa.username}
    <br>
    ${map.bb.username}
    
    
    
    • 效果:

    • 如果Map集合存储的关键字是一个数字,就不能使用"."号运算符了,如下所示

    • 对于这种情况,我们可以使用"[]"的形式读取Map集合的数据
    
    ${map["1"].username}
    <br>
    ${map["2"].username}
    
    
    
    • EL表达式配合JSTL标签可以很方便的迭代集合,后面讲到JSTL标签的时候会用到!这里就不详细说明了。

    EL运算符

    • EL表达式支持简单的运算符:加减乘除取摸,逻辑运算符empty运算符(判断是否为null),三目运算符

    • empty运算符可以判断对象是否为null,用作于流程控制!
    • 三目运算符简化了if和else语句,简化代码书写
    
    <%
        List<Person> list = null;
    %>
    
    ${list==null?"list集合为空":"list集合不为空"}
    
    
    • 效果:


    EL表达式11个内置对象

    EL表达式主要是来对内容的显示,为了显示的方便,EL表达式提供了11个内置对象

    1. pageContext 对应于JSP页面中的pageContext对象(注意:取的是pageContext对象)
    2. pageScope 代表page域中用于保存属性的Map对象
    3. requestScope 代表request域中用于保存属性的Map对象
    4. sessionScope 代表session域中用于保存属性的Map对象
    5. applicationScope 代表application域中用于保存属性的Map对象
    6. param 表示一个保存了所有请求参数的Map对象
    7. paramValues表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
    8. header 表示一个保存了所有http请求头字段的Map对象
    9. headerValues同上,返回string[]数组。
    10. cookie 表示一个保存了所有cookie的Map对象
    11. initParam 表示一个保存了所有web应用初始化参数的map对象
    • 下面测试各个内置对象
    
    <%--pageContext内置对象--%>
    <%
        pageContext.setAttribute("pageContext1", "pageContext");
    %>
    pageContext内置对象:${pageContext.getAttribute("pageContext1")}
    <br>
    
    <%--pageScope内置对象--%>
    <%
        pageContext.setAttribute("pageScope1","pageScope");
    %>
    pageScope内置对象:${pageScope.pageScope1}
    <br>
    
    <%--requestScope内置对象--%>
    <%
        request.setAttribute("request1","reqeust");
    %>
    requestScope内置对象:${requestScope.request1}
    <br>
    
    <%--sessionScope内置对象--%>
    <%
        session.setAttribute("session1", "session");
    %>
    sessionScope内置对象:${sessionScope.session1}
    <br>
    
    <%--applicationScope内置对象--%>
    <%
        application.setAttribute("application1","application");
    %>
    applicationScopt内置对象:${applicationScope.application1}
    <br>
    
    <%--header内置对象--%>
    header内置对象:${header.Host}
    <br>
    
    <%--headerValues内置对象,取出第一个Cookie--%>
    headerValues内置对象:${headerValues.Cookie[0]}
    <br>
    
    
    <%--Cookie内置对象--%>
    <%
        Cookie cookie = new Cookie("Cookie1", "cookie");
    %>
    Cookie内置对象:${cookie.JSESSIONID.value}
    <br>
    
    <%--initParam内置对象,需要为该Context配置参数才能看出效果【jsp配置的无效!亲测】--%>
    
    initParam内置对象:${initParam.name}
    
    <br>
    
    
    
    • 效果图:

    注意事项:

    • 测试headerValues时,如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]

    • 测试cookie时,例${cookie.key}取的是cookie对象,如访问cookie的名称和值,须${cookie.key.name}${cookie.key.value}

    • 测试initParam时,初始化参数要的web.xml中的配置Context的,仅仅是jsp的参数是获取不到的

    • 上面已经测过了9个内置对象了,至于param和parmaValues内置对象一般都是别的页面带数据过来的(表单、地址栏)

    • 表单页面

    
    <form action="/zhongfucheng/1.jsp" method="post">
    用户名:<input type="text" name="username"><br>
    年龄:<input type="text " name="age"><br>
    爱好:
    <input type="checkbox" name="hobbies" value="football">足球
    <input type="checkbox" name="hobbies" value="basketball">篮球
    <input type="checkbox" name="hobbies" value="table tennis">兵乓球<br>
    <input type="submit" value="提交"><br>
    </form>
    
    
    • 处理表单页面:
    
    
    ${param.username}
    <br>
    
    ${param.age}
    <br>
    
    //没有学习jstl之前就一个一个写吧。
    ${paramValues.hobbies[0]}
    <br>
    
    ${paramValues.hobbies[1]}
    <br>
    
    ${paramValues.hobbies[2]}
    <br>
    
    
    • 效果:

    • 当然了,使用地址栏方式提交数据给处理页面也是用param内置对象去获取数据的


    EL表达式回显数据

    EL表达式最大的特点就是:如果获取到的数据为null,输出空白字符串""!这个特点可以让我们数据回显

    • 在1.jsp中模拟场景
    
    <%--模拟数据回显场景--%>
    <%
        User user = new User();
        user.setGender("male");
    
        //数据回显
        request.setAttribute("user",user);
    %>
    
    
    <input type="radio" name="gender" value="male" ${user.gender=='male'?'checked':'' }>男
    <input type="radio" name="gender" value="female" ${user.gender=='female'?'checked':'' }>女
    
    
    
    • 效果:


    EL自定义函数

    EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能

    • 开发HTML转义的EL函数
    • 我们有时候想在JSP页面中输出JSP代码,但是JSP引擎会自动把HTML代码解析,输出给浏览器。此时我们就要对HTML代码转义

    步骤:

    • 编写一个包含静态方法的类EL表达式只能调用静态方法),该方法很常用,Tomcat都有此方法,可在webappsexamplesWEB-INFclassesutil中找到
    
    public static String filter(String message) {
    
        if (message == null)
            return (null);
    
        char content[] = new char[message.length()];
        message.getChars(0, message.length(), content, 0);
        StringBuilder result = new StringBuilder(content.length + 50);
        for (int i = 0; i < content.length; i++) {
            switch (content[i]) {
            case '<':
                result.append("&lt;");
                break;
            case '>':
                result.append("&gt;");
                break;
            case '&':
                result.append("&amp;");
                break;
            case '"':
                result.append("&quot;");
                break;
            default:
                result.append(content[i]);
            }
        }
        return (result.toString());
    
    }
    
    
    • 在WEB/INF下创建tld(taglib description)文件,在tld文件中描述自定义函数
    
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <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">
    
        <tlib-version>1.0</tlib-version>
        <short-name>myshortname</short-name>
        <uri>/zhongfucheng</uri>
    
        <!--函数的描述-->
        <function>
    
            <!--函数的名字-->
            <name>filter</name>
    
            <!--函数位置-->
            <function-class>utils.HTMLFilter</function-class>
    
            <!--函数的方法声明-->
            <function-signature>java.lang.String filter(java.lang.String)</function-signature>
        </function>
    
    </taglib>
    
    
    
    • 在JSP页面中导入和使用自定义函数,EL自定义的函数一般前缀为"fn",uri是"/WEB-INF/tld文件名称"
    
    <%@ page language="java" contentType="text/html" pageEncoding="UTF-8" %>
    <%@taglib prefix="fn" uri="/WEB-INF/zhongfucheng.tld" %>
    
    
    <html>
    <head>
        <title></title>
    </head>
    <body>
    
    //完成了HTML转义的功能
    ${fn:filter("<a href='#'>点我</a>")}
    
    
    </body>
    </html>
    
    
    
    • 效果:


    EL函数库(fn方法库)

    • 由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,SUN公司针对于一些常见处理定义了一套EL函数库供开发者使用

    • 其实EL函数库就是fn方法库,是JSTL标签库中的一个库,也有人称之为fn标签库,但是该库长得不像是标签,所以称之为fn方法库

    • 既然作为JSTL标签库中的一个库,要使用fn方法库就需要导入JSTL标签要想使用JSTL标签库就要导入jstl.jar和standard.jar包!

    • 所以,要对fn方法库做测试,首先导入开发包(jstl.jar、standard.jar)

    • 在JSP页面中指明使用标签库
    
    <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    
    
    • fn方法库全都是跟字符串有关的(可以把它想成是String的方法)

    • fn:toLowerCase

    • fn:toUpperCase

    • fn:trim

    • fn:length

    • fn:split

    • fn:join 【接收字符数组,拼接字符串】

    • fn:indexOf

    • fn:contains

    • fn:startsWith

    • fn:replace

    • fn:substring

    • fn:substringAfter

    • fn:endsWith

    • fn:escapeXml【忽略XML标记字符】

    • fn:substringBefore

    • 测试代码:

    contains:${fn:contains("zhongfucheng",zhong )}<br>
    
    containsIgnoreCase:${fn:containsIgnoreCase("zhongfucheng",ZHONG )}<br>
    
    endsWith:${fn:endsWith("zhongfucheng","eng" )}<br>
    
    escapeXml:${fn:escapeXml("<zhongfucheng>你是谁呀</zhongfucheng>")}<br>
    
    indexOf:${fn:indexOf("zhongfucheng","g" )}<br>
    
    length:${fn:length("zhongfucheng")}<br>
    
    replace:${fn:replace("zhongfucheng","zhong" ,"ou" )}<br>
    
    split:${fn:split("zhong,fu,cheng","," )}<br>
    
    startsWith:${fn:startsWith("zhongfucheng","zho" )}<br>
    
    substring:${fn:substring("zhongfucheng","2" , fn:length("zhongfucheng"))}<br>
    
    substringAfter:${fn:substringAfter("zhongfucheng","zhong" )}<br>
    
    substringBefore:${fn:substringBefore("zhongfucheng","fu" )}<br>
    
    toLowerCase:${fn:toLowerCase("zhonGFUcheng")}<br>
    
    toUpperCase:${fn:toUpperCase("zhongFUcheng")}<br>
    
    trim:${fn:trim("              zhong    fucheng    ")}<br>
    
    <%--将分割成的字符数组用"."拼接成一个字符串--%>
    join:${fn:join(fn:split("zhong,fu,cheng","," ),"." )}<br>
    
    
    • 效果:

    • 使用fn方法库数据回显
    
    <%
        User user = new User();
        String likes[] = {"sing"};
        user.setLikes(likes);
    
        //数据回显
        request.setAttribute("user",user);
    %>
    
    
    <%--java的字符数组以","号分割开,首先拼接成一个字符串,再判读该字符串有没有包含关键字,如果有就checked--%>
    <input type="checkbox"${ fn:contains(fn:join(user.likes,","),"sing")?'checked':'' }>唱歌
    <input type="checkbox"${ fn:contains(fn:join(user.likes,","),"dance")?'checked':'' }>跳舞
    
    
    • 效果:


    如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,可以关注微信公众号:Java3y

  • 相关阅读:
    Win8系统 Python安装
    一些安卓开源框架整理
    Android 媒体键监听以及模拟媒体键盘的实现 demo
    android View 自动 GONE 问题
    Android 定时器TimerTask 简单使用
    关于Android studio 相对 eclipse 优点
    Java序列化与反序列化
    android shape的使用 边框
    Android Studio 修改 包名 package name
    Android WebView Long Press长按保存图片到手机
  • 原文地址:https://www.cnblogs.com/Java3y/p/8422437.html
Copyright © 2011-2022 走看看