美文网首页
三、EL表达式和JSTL

三、EL表达式和JSTL

作者: 艾特小师叔 | 来源:发表于2020-03-13 22:51 被阅读0次

EL表达式和JSTL标签

在JavaWeb中,JSP技术提供9大内置对象,其中4个对象(四大作用域)用于存储数据,且可用于数据的传递。但是从四大作用域中,获取数据相对麻烦,且不利于结算,编码风格也相对不友善,因为需要在HTML页面中,使用<%%>等书写Java代码,基于这样的考虑,JavaWeb提供了EL表达式,用于弥补这个不足。EL表达式,支持从四大作用域中,获取数据,则支持简单运算,就不再使用Java代码,进行值相关操作。EL表达式,只需要是用:

${表达式}即可,语法相对简单,且更加友善。

1.EL表达式获取值

EL表达式获取值,主要是从四大作用域中获取值,且获取的顺序,分别是从小到大获取,即:优先从 pageContext --> request ----> session ----> applcation。一旦获取到数据,将不会再从下一个容器获取,如果所有的容器,都没有被获取的数据,那么则返回空字符串。注意:在Java中,若作用域中没有数据,则返回:null.如果页面显示一个null,这样很不友善。EL表达式的空字符串,一般用于搜索时的数据回显。

EL表达式主要功能是用于获取数据,其语法如下:

1.1.获取简单的数据

语法

​ ${key}

注意:四大作用域,存储数据的结构是一个key-value结构,所以el表达式默认使用key获取

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式</title>
</head>
<body>
<%
    //向四大作用域存储数据
    pageContext.setAttribute("pageContextKey", "pageContextValue");
    request.setAttribute("requestKey", "requestValue");
    session.setAttribute("sessionKey", "sessionValue");
    application.setAttribute("applicationKey", "applicationValue");

    // 所有的容器中 都存放一样的key
    //pageContext.setAttribute("dataKey", "pageContextValue");
    //request.setAttribute("dataKey", "requestValue");
    //session.setAttribute("dataKey", "sessionValue");
    //application.setAttribute("dataKey", "applicationValue");
%>
<h1>从作用域中取值</h1>
pageContext:<%=pageContext.getAttribute("pageContextKey") %>  <br>
<!-- 使用el表达式  获取值 -->
<%-- ${key} --%>
pageContext:${pageContextKey}  <br>
request:${requestKey}  <br>
session:${sessionKey}  <br>
application:${applicationKey}<br>
<!-- 
    若四大作用域中存储数据的key 一样 
    优先从pageContext获取。
    若都没有则是空字符串

-->
都是dataKey 从哪取值:${dataKey} 
</body>
</html>

1.2.获取JavaBean对象数据

语法:

​ ${key.属性名}

注意:

在el表达式中,默认根据key获取的对象,是获取了对象的地址的字符串,然后可以根据key.属性名获取对应的属性值。但是,属性是私有的,在Java中,是无法根据对象.属性访问私有属性的。而el表达式,通过这样的形式获取了到了属性值,其本质不是对象直接访问属性,而是对象根据属性名,调用同名的get方法获取的属性。

基于这一点,在实际开发中,可以进行数据处理。例如:性别的值是数字,1 是男 2 是女.但是,页面上要显示男或者女.可以定义一个处理数据的get方法,然后,在页面使用el表达式,访问这个方法。

还可以处理时间等等。
示例代码:

package com.sxt.pojo;

public class User {
    
    private Integer id;
    
    //private String name;
    
    private int sex;
    
    
    public User() {}


    public User(Integer id, String name) {
        super();
        this.id = id;
        //this.name = name;
    }


    public Integer getId() {
        return id;
    }


    public void setId(Integer id) {
        this.id = id;
    }


    public String getName() {
        System.out.println("获取 name 的属性值");
        return "韩梅梅";
    }


    public int getSex() {
        
        return sex;
    }

    public String getSexFormat() {
        if(sex == 1) {
            return "男";
        }
        if(sex == 2) {
            return "女";
        }
        return "不详";
    }

    public void setSex(int sex) {
        this.sex = sex;
    }


//  public void setName(String name) {
//      this.name = name;
//  }
    
    

}

<%@page import="com.sxt.pojo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式访问对象数据</title>
</head>
<body>
<%
    //向作用域中添加数据
    User user = new User(1001,"韩梅梅");
    user.setSex(3);
    request.setAttribute("userKey", user);
%>
<!-- 使用EL表达式获取对象数据 -->
获取对象:${userKey} <br>
获取对象中的id属性值:${userKey.id}<br>
获取对象中的name属性值:${userKey.name}<br>
获取对象中的sex属性值:${userKey.sex}<br>
获取对象中的sex显示的值:${userKey.sexFormat}<br>
</body>
</html>

1.3.获取Map结构的数据

语法:

​ ${作用域中的key.map中的key}

程序示例:

<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="com.sxt.pojo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式访问对象数据</title>
</head>
<body>
<%
    Map<String,String> map = new HashMap<String,String>();
    map.put("key","value");
    //将map 放到作用域中
    request.setAttribute("map",map);
    //此时map中存储的是  user类型的值
    Map<String,User> userMap = new HashMap<String,User>();
    User  user = new User();
    user.setId(10001);
    user.setSex(1);
    userMap.put("user1", user);
    //将map 放到作用域中
    request.setAttribute("userMap",userMap);
%>
<!-- el 获取作用域中的map 对象 -->
map 对象: ${map}<br>
map中的值:${map.key}<br>
<hr>
map对象: ${userMap}<br>
map对象中的值对象:${userMap.user1}<br>
map对象中的值对象的属性值:${userMap.user1.id}<br>
map对象中的值对象的属性值:${userMap.user1.sex}<br>
map对象中的值对象的属性值:${userMap.user1.sexFormat}<br>
</body>
</html>

注意:当map中,存储数据的key值特殊时,可以使用['特殊key']的形式获取值。但是存在兼容性。

示例:

<%
    Map<String,User> userMap = new HashMap<String,User>();
    User  user = new User();
    user.setId(10001);
    user.setSex(1);
    userMap.put("1", user);//注意 此时使用 1 作为key   el表达式是不支持
    //将map 放到作用域中   
    request.setAttribute("userMap",userMap);
%>
map对象中的值对象:${userMap['1']}<br>
map对象中的值对象的属性值:${userMap['1'].id}<br>

1.4.获取数组结构的数据

语法:

${key[索引]}

示例:

<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="com.sxt.pojo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式访问数组对象数据</title>
</head>
<body>
<%  
    // 创建一个数组结构容器
    List<String> strs = new ArrayList<String>();
    strs.add("韩梅梅");
    strs.add("李磊");
    strs.add("Jim");
    strs.add("Lucy");
    //将数据放入到作用域中
    request.setAttribute("strs", strs);
    List<User> users = new ArrayList<User>();
    User user = new User();
    user.setId(1001);
    user.setSex(1);
    users.add(user);//将java对象放入到list数组中
    //将数据放入到作用域中
    request.setAttribute("users", users);
    
%>
<!-- el 获取作用域中的数组 对象 -->
获取List数组结构对象:${strs}<br>
获取List中具体的元素:${strs[0]}   &nbsp;${strs[1]}&nbsp; ${strs[2]} &nbsp; ${strs[3]} 
<!-- 数组中存储的是Java对象 -->
<hr>
获取数组中的对象:${users[0]}<br>
获取数组中对象的属性值:${users[0].id}<br>
</body>
</html>

2.EL表达式的运算

2.1.算术运算

在el表达式中,也支持算术运算符:

运算符 说明
+ 算术加
- 算术减
* 算术乘
/ 算术除以
% 算术取余数

代码示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>el表达式中的算术运算符</title>
</head>
<body>
<%
    //将整数10  放入了作用域
    request.setAttribute("m", 10);
    request.setAttribute("n", 2);
%>
<p>11---加法运算:${m+1}</p> 
<p>9---减法运算:${m-1}</p>
<p>20---乘法运算:${m*2}</p>
<p>5----除法运算:${m/2}</p>
<p>1----取模运算:${m%3}</p>
<hr>
<p>12---加法运算:${m+n}</p> 
<p>8---减法运算:${m-n}</p>
<p>20---乘法运算:${m*n}</p>
<p>5----除法运算:${m/n}</p>
<p>0----取模运算:${m%n}</p>
</body>
</html>

2.2.关系运算

EL表达式中支持关系运算符

符号 等价符号 说明
> gt 大于
>= ge 大于等于
< lt 小于
<= le 小于等于
== eq 等于
!= ne 不等于

代码示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>el表达式中的关系运算符</title>
</head>
<body>
<%
    //将整数10  放入了作用域
    request.setAttribute("m", 10);
    request.setAttribute("n", 10);
%>
<p>false----大于运算符:${m>n}</p> 
<p>true ----大于等于运算符:${m>=n}</p> 
<p>false ----小于运算符:${m<n}</p> 
<p>true ----小于等于运算符:${m<=n}</p> 
<p>true ----等于运算符:${m==n}</p> 
<p>false ----不等于运算符:${m!=n}</p> 
<hr>
<p>false----大于运算符:${m gt n}</p> 
<p>true ----大于等于运算符:${m ge n}</p> 
<p>false ----小于运算符:${m lt n}</p> 
<p>true ----小于等于运算符:${m le n}</p> 
<p>true ----等于运算符:${m eq n}</p> 
<p>false ----不等于运算符:${m ne n}</p> 

</body>
</html>

注意:使用等价符号是,符号两边需要空格

2.3.逻辑运算

在EL表达式中,也支持逻辑运算符。

符号 等价符号 说明
&& and 并且
|| or
not 取反

代码示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式逻辑运算符</title>
</head>
<body>
<p>false ---- &&运算符: ${false && true}   </p>
<p>true ---- ||运算符: ${false || true}   </p>
<p>true ---- !运算符: ${!false}   </p>
<hr>
<p>false ---- and运算符: ${true and false}   </p>
<p>true ---- or运算符: ${false or true}   </p>
<p>true ---- not运算符: ${not false}   </p>
</body>
</html>

2.4.三元运算

EL表达式中也支持三元运算符,语法:${表达式?值1:值2},若表达式值为true,则返回值1,否则返回值2。

语法示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>三元运算符</title>
</head>
<body>
<%
    request.setAttribute("like", 2);
    request.setAttribute("sex", 2);
%>
${5<2?"韩梅梅":"李磊"}
<!--  使用三元运算符  为标签新增属性 -->
<input type="radio"  name="sex"  ${sex == 1?'checked':""}    />男
<input type="radio"  name="sex"  ${sex == 2?'checked':""}    />女

<input type="checkbox"  ${like == 1?'checked':""}   />篮球
</body>
</html>

2.5.empty运算符

empty运算符,用于判断字符串或者数组是一个空的数据或者null.即:当字符串为空字符串或者为null时,

当数组为空数组或者为null时,empty 都会返回true。

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>empty运算符</title>
</head>
<body>
<%
    String str1 = null; //此时值是null
    String str2 = ""; //此时值是空字符串
    List<String> list1 = null;// 此时数组为null
    List<String> list2 = new ArrayList<String>();// 此时数组为空数组
%>
<p>null值的字符串:${empty str1}</p>
<p>空值的字符串:${empty str2}</p>
<p>null值的数组:${empty list1}</p>
<p>空值的数组:${empty list2}</p>
<h1>场景: 循环一个List   如果List 为空则显示没有符合条件的数据</h1>
${empty list2?"没有符合条件的数据":"存在符合条件的数据" }
</body>
</html>

3.EL表达式中内置对象

EL表达式,默认是从最小作用域,取值直到最大的作用域,如果出现作用域数据的重叠,想要精确的取到指定作用域的值,那么就需要从EL表达式中,获取对应的作用域,然后进行取值。

序 号 隐含对象名称 描 述
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[]数组。注意:如果头里面有“-” ,例Accept Encoding,则要headerValues[“Accept-Encoding”]
10 cookie 表示一个保存了所有cookie的Map对象
11 initParam 表示一个保存了所有web应用初始化参数的map对象

代码示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式内置对象</title>
</head>
<body>
<%
    pageContext.setAttribute("key", "pageValue");
    request.setAttribute("key", "requestValue");
    session.setAttribute("key", "sessionValue");
    application.setAttribute("key", "applicationValue");

%>
<!-- 
    以上4个作用域 都存了一个键的值为key 值为对应的值的键值对
    而EL表达式 默认从pageContext 获取  所以,其他三个作用域 的值就无法获取到。
    所以el表达式,提供了:
        pageScope  表示pageContext 作用域
        requestScope 表示request 作用域
        sessionScope 表示session 作用域
        applicationScope 表示 application作用域
 -->
 <!-- 获取pageContext对象 -->
 ${pageContext}<br>
 <!-- 从pageContext 作用域中取值 -->
 ${pageScope.key}  :=====>pageValue<br>
  <!-- 从reuqest 作用域中取值 -->
 ${requestScope.key} :====>requestValue<br>
    <!-- 从session 作用域中取值 -->
 ${sessionScope.key} :====>sessionValue<br>
   <!-- 从 application 作用域中取值 -->
 ${applicationScope.key}:====>applicationValue<br>
 <hr>
 获取请求参数:${param.name}<br>
   获取数组类型请求参数:${paramValues.name[0]}<br>
  获取数组类型请求参数:${paramValues.name[1]}<br>
  <hr>
  请求头:${header.Host}<br>
 请求头中数组类型值:${headerValues['Accept-Encoding'][0]} <br>
  请求头中数组类型值:${headerValues['Accept-Encoding'][1]} <br>
</body>
</html>

4.EL表达式的优缺点

EL表达式,基本上可以在JSP页面中任意地方都可以进行书写。但是,其值只能支持字符串。相对于Java而言,取值更加方便。但是EL表达式,没有条件分支判断,也不支持循环。所以,若页面数据,需要进行条件分支判断,和循环处理,纯粹只靠EL表达式,是无法满足真正的需求的。需要使用JSTL进行补充。

5.JSTL

JSTL(Java server pages standarded tag library,即JSP标准标签库)是由JCP(Java community
Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的
Jakarta小组来维护。开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,
降低程序的维护难度。

5.1.JSTL入门使用

JSTL是Apache的Jakarta小组维护,JSTL是属于第三方技术。所以,需要引入相关的jar包。

5.1.1.引入相关jar包

jstl-1.2.jar
standard-1.1.2.jar

5.1.2.在页面引入标签库

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

由于,jstl标签前缀一般使用c,所以也被称之为c标签。

5.1.3.使用<c:作为前缀,自动提示可用的标签。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- 引入 jstl 标签库 -->
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:if test="${5<2}">
    如果表达式的值为true,则我会显示
</c:if>
</body>
</html>

5.2.JSTL中常用标签

5.2.1.条件分支标签

<!-- 单条件分支标签 -->
语法:
<c:if test="el表达式">代码</c:if>
语法说明:
   若test中el表达式的最终运算结果为true,则执行被包裹的代码    
       
<!-- 多条件分支标签 -->
语法:
<c:choose>
    <c:when test="el表达式">代码块1</c:when>
    ....
    <c:when test="el表达式">代码块n</c:when> 
    <c:otherwise>代码块n+1</c:otherwise>   
</c:choose>    
语法解释:
    执行when后面 test中的el表达式,自上而下执行,若满足条件,则运行被包裹的代码块,且后面的when标签包裹的test不再进行判定执行,若所有的test都不满足,则运行otherwise包裹的代码块。

代码示例

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <!-- 引入 jstl 标签库 -->
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:if test="${5<2}">
    如果表达式的值为true,则我会显示
</c:if>
<h1>条件分支</h1>
<h2>if条件分支</h2>
<c:if test="${5<2}">
    如果表达式的值为true,则我会显示
</c:if>
<h2>多条件分支</h2>
<c:choose >
    <c:when test="${10<2}"><!-- false -->
        我是第23行<br>
    </c:when>
    <c:when test="${10<3}"><!-- false -->
        我是第26行<br>
    </c:when>
    <c:otherwise>
        我是第29行<br>
    </c:otherwise>
</c:choose>
</body>
</html>

5.2.2.循环标签

循环标签:
<c:forEach begin="" end=""  items=""  var="" step="" varStatus=""></c:forEach>

语法:

属性 说明
items 代循环的数据
var 指代被循环的容器中的元素
step 每次循环增长的步长,默认值1
begin 开始循环的下标索引
end 结束循环的下标索引
varStatus 指代循环的状态信息:
index :当前索引
count:循环的次数
first:是否第一个
last:是否第一个

代码示例:

<%
    List<String> strs = new ArrayList<String>();
    strs.add("字符串1");
    strs.add("字符串2");
    strs.add("字符串3");
    strs.add("字符串4");
    //将数组放入作用域
    request.setAttribute("strs", strs);
%>
<h1>循环配置</h1>
<!-- 
    items="${strs}" : 指代被循环的List  从作用域中获取数组值
    var="str" : 指代 list中存储的数据
    step="2" : 指代每次循环增长下标基数值  默认是按1增长
    begin="1" : 指开始循环的下标索引,默认是从0开始
    end="2" : 结束循环的下标索引
    varStatus="statu" :循环的状态信息,statu就含有当前循环的所有状态信息
        index :下标索引
        count :循环的次数
        first :是否是第一个元素
        last : 是否是第二个元素
 -->
<c:forEach items="${strs}" var="str" step="1" begin="0"  end="3" varStatus="statu">
    ${str}&nbsp;&nbsp;&nbsp;&nbsp;${statu.index}&nbsp;&nbsp;&nbsp;&nbsp;${statu.count}&nbsp;&nbsp;&nbsp;&nbsp;${statu.first} &nbsp;&nbsp;&nbsp;&nbsp;${statu.last}<br>
</c:forEach>
循环结果.png

5.2.3.格式化标签

在实际开发中,很多时候,需要对数字,时间等等进行格式,JSTL提供了一套格式化的标签库。

可以参考:https://www.runoob.com/jsp/jsp-jstl.html

时间格式化标签

1.在页面引入jstl标签库

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

2.使用相应的时间格式化标签

<h1>时间格式化标签</h1>
<!-- 
    value :待格式化的时间数据
    pattern : 具体的格式
    var : 用于表示被格式化后的字符串,可以在其它地方应用该值
 -->
 <%
    request.setAttribute("createTime", new Date());
 %>
 没有格式化的时间数据:${createTime}<br>
<fmt:formatDate value="${createTime}" pattern="yyyy-MM-dd HH:mm:ss" var="formatTime" />
${formatTime}<br>
${formatTime}<br>
${formatTime}<br>
${formatTime}<br>

相关文章

网友评论

      本文标题:三、EL表达式和JSTL

      本文链接:https://www.haomeiwen.com/subject/gnxushtx.html