EL表达式

JAVAWEB 专栏收录该内容
1 篇文章 0 订阅

博主是一名初学者,希望评论区的大佬手下留情,我会分享今后自己在学习过程中的遇到的问题以及笔记,希望大家能够指点一二,谢谢!!!文章中有侵犯各位权益的,忘提醒一下,我会进行删除。

1.EL表达式简介

Expression Language表达式语言 是一种在JSP页面获取数据的简单方式(只能获取数据,不能设置数据)
在JSP2.0开始引入概念 语法格式 在JSP页面的任何静态部分均可通过:${expression}来获取到指定表达式的值
大多数Java
Web服务器都是默认支持EL的。JSP页面默认支持EL,如果不支持的话,我们可以通过设置page指令的 isELIgnored属性为false,来实现对EL的支持。
对于单个JSP页面,可以使用page指令来设置JSP页面是否支持EL。

<%@page isElIgnored="false || true"%>   //isElIgnored属性表示是否忽略EL表达式

对于整个JSP应用,要修改Web应用的web.xml配置文件来设置是否支持EL。

<jsp-property-group>
    <el-ignored>[false || true]</el-ignored> //el-ignored属性表示整个JSP应用是否支持EL。
</jsp-property-group>

2.EL使用

获取数据(在jsp页面中)

EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。
EL表达式可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据

<%
    request.setAttribute("name","张三");
%>
<%--${name}相当于 pageContext.findAttribute("name");--%>
使用EL表达式获取数据:${name}

获取字符串数组中的数据

<%
    String[] names= {"zhang","wang","li","zhao"};
    request.setAttribute("names",names);
%>
数组中的数据:name[1]=${names[1]}   name[3]=${names[3]}

访问类数组中的数据

<%
    Stu[] stus=new Stu[3];
    stus[0]=new Stu(1,"zhangsa");
    stus[1]=new Stu(2,"lisi");
    stus[2]=new Stu(3,"wangwu");
    request.setAttribute("stus",stus);
%>
类数组中的数据:stu.name[1]=${stus[1].name} 

获取bean的属性

<%
    Admin admin=new Admin();
    admin.setId(1);
    admin.setName("张三");
    admin.setDate(new Date());
    request.setAttribute("admin",admin);
%>
使用EL表达式获取bean的属性:${admin.id}--${admin.name}==${admin.date}

获取bean中属性为另一个bean的属性

<%
    Admin admin1=new Admin();
    Son son=new Son();
    son.setName("李四");
    admin1.setSon(son);
    request.setAttribute("admin1",admin1);
%>
使用EL表达式获取bean中属性为另一个bean的属性:${admin1.son.name}

获取list集合中指定位置的数据

<%
    Son son1=new Son();
    son1.setName("张三");
    Son son2=new Son();
    son2.setName("李四");
    List<Son> list=new ArrayList<Son>();
    list.add(son1);
    list.add(son2);
    request.setAttribute("list",list);
%>
获取list集合中指定位置的数据:${list[0].name}    ${list[1].name}
迭代List集合中的数据:
<c:forEach var="s" items="${list}">
    ${s.name}
</c:forEach>

碰到的问题: jsp页面中的Java代码集合中的子类的泛型不能省略,否则报ClassNotFoundException异常信息 集合中获取指定位置的数据索引是从0开始的

使用<c:forEach>迭代list集合的时候,jsp页面要使用c标签,应该导入

<%@ taglib uri = " http://java.sun.com/jsp/jstl/core " prefix = "c" %>

当你导入后发现报错,是因为缺少JSTL的依赖

<dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
    </dependency>

当你有了JSTL的API后发现问题并没有解决,是因为我们只是导入了jstl-api,而没有导入jstl的实现

<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>

使用el表达式获取map集合的数据

<%
    Map<String,String> map=new LinkedHashMap<String,String>();
    map.put("a","1");
    map.put("b","2");
    map.put("c","3");
    map.put("d","4");
    request.setAttribute("map",map);
%>
根据关键字获取map的数据:${map.a}   ${map['c']}
迭代map集合中的数据:
<c:forEach var="me" items="${map}">
    ${me.key}=${me.value}
</c:forEach>

执行运算

语法:${运算表达式},EL表达式支持如下运算符:
关系运算符:

( ),+,-,*,/ or div,== or eq,!= or ne,< or lt,> or gt,<= or le,>= or ge

逻辑运算符:

&& or and,|| or or,! or not

. 和 [ ] :

s e s s i o n S c o p e . u s e r . s e x 等 于 {sessionScope.user.sex}等于 sessionScope.user.sex{sessionScope.user[“sex”]}都是要获取 user对象
sex属性的值。 如果对象的属性带有特殊字符例如 ‘.’ , ‘-’ 就一定要是用 ’ [ ] ’ 来获取对象的属性值
如果要单纯的获取一个变量,而这个变量的值是 对象的属性的时候。也就是说此时是动态的获取值。

req.setAttribute("user",new User(1,"张三"));
req.setAttribute("aaa","name");//aaa的值表示为name,而name是user对象的name属性

在页面上 使用 s e s s i o n S c o p e . u s e r [ a a a ] 获 取 n a m e 属 性 的 值 此 时 , a a a 是 一 个 变 量 , 它 的 值 为 n a m e 那 上 述 的 例 子 等 于 {sessionScope.user[aaa]} 获取name属性的值 此时,aaa是一个变量,它的值为 name 那上述的例子等于 sessionScope.user[aaa]nameaaaname{sessionScope.user.name};

总结:一般使用[] 进行获取 含有特殊字符的 对象属性 。获取正常情况下的属性一般使用点 .
动态取值也不会用到它,使用jstl进行判断之后动态取值。或者直接在java代码写好逻辑。 empty运算符

使用empty运算符检查对象是否为null(空)

<c:if test="${!empty(list)}">
    <c:forEach var="str" items="${list}">
        ${str}
     </c:forEach>
35 </c:if>

EL表达式数据的回显

<% 
    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':''}>女

获取web开发常用对象

EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${隐式对象名称}:获得对象的引用

域属性相关的内置对象(四个):只能从四大域中获取属性
pageScope:代表page域中用于保存属性的Map对象

<%
    pageContext.setAttribute("name", "linjie");
%>
page域:name=${pageScope.name }

requestScope:代表request域中用于保存属性的Map对象

<%
    request.setAttribute("name", "lucy");
%>
request域:name=${requestScope.name }

sessionScope:代表session域中用于保存属性的Map对象

<%
    session.setAttribute("name", "king");
%>
session域:name=${sessionScope.name }

applicationScope:代表application域中用于保存属性的Map对象

<%
    application.setAttribute("name", "bilibili");
%>
application域:name=${applicationScope.name }

其他重要的内置对象(四个)

pageContext:(注意:取的是pageContext对象。)
该pageContext与JSP内置对象pageContext是同一个对象。通过该对象,可以获取到request、response、session、servletContext、servletConfig等对象注意:这些对象在EL里不是内置对象,这些对象只能通过pageContext获取

例如: p a g e C o n t e x t . r e q u e s t 即 可 获 取 r e q u e s t 对 象 , 其 底 层 调 用 的 是 p a g e C o n t e x t . g e t R e q u e s t ( ) 方 法 常 用 于 {pageContext.request}即可获取request对象,其底层调用的是pageContext.getRequest()方法 常用于 pageContext.requestrequestpageContext.getRequest(){pageContext.request.contextPath}来代表WEB的根目录

<form action="${pageContext.request.contextPath }/regster" method="POST">
        xxx<input type="text" name="name"/><br>
        yyy<input type="text" name="age"/><br>
        <input type="submit" value="点击">
</form>

param:表示一个保存了所有请求参数的Map对象,其底层实际调用request.getParameter(),用来获取请求中指定的参数

<form action="${pageContext.request.contextPath }/regster" method="POST">
        xxx<input type="text" name="name"/><br>
        yyy<input type="text" name="age"/><br>
        <input type="submit" value="点击">
</form>


<body>
    name=${param.name }
    age=${param.age }
</body>

paramValues:获取请求中的指定参数的所有值,其底层实际调用request.getParameterValues(),返回的是一个字符串数组

<form action="${pageContext.request.contextPath }/regster" method="POST">
       <input type="checkbox" name="hobby" value="sleep">睡觉
        <input type="checkbox" name="hobby" value="play">玩
        <input type="checkbox" name="hobby" value="eat">吃
        <input type="submit" value="点击">
</form>

<body>
    hobby[0]=${paramValues.hobby[0] }<br>
    hobby[1]=${paramValues.hobby[1] }<br>
</body>

initParam:获取初始化参数,其底层调用的是ServletContext.getInitParameter()

<!--初始化参数 -->
  <context-param>
    <param-name>name</param-name>
    <param-value>林杰</param-value>
  </context-param>
<body>
    name=${initParam.name }
</body>

其他

header:表示一个保存了所有http请求头字段的Map对象,注意:如果头里面有“-”
,例Accept-Encoding,则要header[“Accept-Encoding”]
headerValues:表示一个保存了所有http请求头字段的Map对象,它对于某个请求参数,返回的是一个string[]数组。注意:如果头里面有“-”
,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
cookie:表示一个保存了所有cookie的Map对象

注意:

EL的11个内置对象,除了pageContext以外,其他10个内置对象的类型都是java.util.Map类型

调用Java方法

EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。语法:${prefix:method(params)}
在EL表达式中调用的只能是Java类的静态方法,这个Java类的静态方法需要在TLD文件中描述,才可以被EL表达式调用。
EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。

3.EL取值原理

取值原理
以表达式${admin.name}为例

EL表达式会根据name去admin类里寻找这个name的getter方法,此时会自动把name首字母大写并加上get前缀,一旦找到与之匹配的方法,El表达式就会认为这就是要访问的属性,并返回return的值。
(提示:不用大写也是可以的,自测过了)重点是开发的时候遇到这种问题多留意下提到的这几点。但是getset方法是必须要有的。
所以,想要通过EL表达式获取对象属性的值,那么这个属性就必须有与之对应的getter方法。且return返回的值要正确。(必须使用快捷键方式创建setter和getter方法),
作用域取值的顺序 EL
存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。可是并没有指定哪一个范围的username,所以它的默认值会先从Page范围找,假如找不到,再依序到RequestSessionApplication范围。假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null,EL表达式还会做出优化,页面上显示空白,而不是打印输出NULL。

4.EL的11大隐含对象

pageScope page 作用域
requestScope request 作用域
sessionScope session 作用域
applicationScope application 作用域
param Request 对象的参数,字符串
paramValues Request对象的参数,字符串集合
header HTTP 信息头,字符串
headerValues HTTP 信息头,字符串集合
initParam 上下文初始化参数
cookie Cookie值
pageContext 当前页面的pageContext

5.自定义EL函数

EL自定义函数的开发以及应用一般分为三个步骤

1,编写一个Java类的静态方法
2,编写标签库描述符(tld)文件,在tld文件中描述自定义函数
3,在jsp页面导入和使用自定义函数

例如:编写对页面标签进行转义的自定义EL函数

编写转换处理的工具类

public class HtmlFilter {
    public static String filter(String message) {
        if (message == null || message == "") {
            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("a");
                    break;
                case '>':
                    result.append("b");
                    break;
                case '&':
                    result.append("c");
                    break;
                case '"':
                    result.append("d");
                    break;
                default:
                    result.append(content[i]);
            }
        }
        return result.toString();
    }
}

在WEB-INF目录下编写标签库描述符(tld)文件,在tld文件中描述自定义函数

<?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>elf</short-name>
    <!--
     自定义EL函数库的引用URI,
     在JSP页面中可以这样引用:<%@taglib uri="/ELFunction" prefix="fn" %>
  -->
    <uri>/ELFunction</uri>
    <!--<function>元素用于描述一个EL自定义函数 -->
    <function>
        <!--<name>子元素用于指定EL自定义函数的名称-->
        <name>filter</name>
        <!--<function-class>子元素用于指定完整的Java类名-->
        <function-class>com.empty.HtmlFilter</function-class>
        <!--<function-signature>子元素用于指定Java类中的静态方法的签名,
             方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔。-->
        <function-signature>java.lang.String filter(java.lang.String)</function-signature>
    </function>

</taglib>

在页面中导入

<%@ taglib uri="/ELFunction" prefix="fn"%>

使用

${fn:filter("<title></title>")}

运行后输出

atitleba/titleb

6.EL函数库

由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,SUN公司针对于一些常见处理定义了一套EL函数库供开发者使用。
  这些EL函数在JSTL开发包中进行描述,因此在JSP页面中使用SUN公司的EL函数库,需要导入JSTL开发包,并在页面中导入EL函数库。
引入EL函数库

<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

EL函数库常用的方法

String toUpperCase(String input):将一个字符串中包含的所有字符转换为大写形式,并返回转换后的字符串,
String toLowerCase(String input):将一个字符串中包含的所有字符转换为小写形式,并返回转换后的字符串,
int indexOf(String input, String substring):返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,那么,不管第二个参数字符串在第一个参数字符串中出现几次,fn:indexOf函数总是返回第一次出现的索引值;如果第一个参数中不包含第二个参数,则fn:indexOf函数返回-1。如果第二个参数为空字符串,则fn:indexOf函数总是返回0。
boolean contains(String input, String substring):检测一个字符串中是否包含指定的字符串,返回值为布尔类型。比较两个字符串是否相等时是大小写敏感的。
boolean containsIgnoreCase(String input, String substring):
boolean startsWith(String input, String substring):用于检测一个字符串是否是以指定字符串开始的,返回值为布尔类型。如果第一个参数字符串以第二个参数字符串开始,则函数返回true,否则函数返回false。
boolean endsWith(String input, String substring):用于检测一个字符串是否是以指定字符串结束的,返回值为布尔类型。
String substring(String input, int beginIndex, int endIndex):用于截取一个字符串的子字符串并返回截取到的子字符串。
tring substringAfter(String input, String substring):用于截取并返回一个字符串中的指定子字符串第一次出现之后的子字符串。第一个参数表示要操作的源字符串,第二个参数表示指定的子字符串
substringBefore(String input, String substring):
String escapeXml(String input):把字符串的“>”、“<”。。。转义了!
String trim(String input):删除一个字符串的首尾的空格,并返回删除空格后的结果字符串,
String replace(String input, String substringBefore, String substringAfter):将一个字符串中包含的指定子字符串替换为其它的指定字符串,并返回替换后的结果字符串。第一个参数表示要操作的源字符串,第二个参数表示源字符串中要被替换的子字符串,第三个参数表示要被替换成的字符串
String[] split(String input, String delimiters):以指定字符串作为分隔符,将一个字符串分割成字符串数组并返回这个字符串数组。第一个参数表示要分割的字符串,第二个参数表示作为分隔符的字符串
int length(Object obj):返回一个集合或数组大小,或返回一个字符串中包含的字符的个数,返回值为int类型。
String join(String array[], String separator):以一个字符串作为分隔符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串。第一个参数是要操作的字符串数组,第二个参数是作为分隔符的字符串。如果fn:join函数的第二个参数是空字符串,则fn:join函数的返回值直接将元素连接起来

使用EL函数库

${fn:toUpperCase("ssddeeYHSTDHdffee"))}//将字符串ssddeeYHSTDHdffee中的小写字母转换成大写并返回。
其他函数不再举例...
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

白茶~乌龙

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值