Hey, Nice to meet You. 

必有过人之节.人情有所不能忍者,匹夫见辱,拔剑而起,挺身而斗,此不足为勇也,天下有大勇者,猝然临之而不惊,无故加之而不怒.此其所挟持者甚大,而其志甚远也.          ☆☆☆所谓豪杰之士,

EL和JSTL表达式的使用

1、EL表达式介绍

EL的全称为Expression Language,即表达式语言,它是JSP内置的表达式语言。EL的用法比较的简单,就是用 ${ 标识符 } 包起来的语句。我们一般用它来读取数据【如:${username} 】或者 执行运算【也就是基本的关系运算、逻辑运算和算术运算如:${username==null}】。使用EL表达式最大的特点就是使用很方便,例如获取用户名 ${username}

EL表达式的特点:

  • 可以自动对获取的数据进行数据类型的转换
  • 若通过EL获取的数据为null,则在页面中什么都不显示
  • EL一般使用访问属性的方式访问数据

下面对比一下在JSP中获取该属性,如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>EL表达式的使用</title>
  </head>
  <body>
  <%
      //在session中设置值
      session.setAttribute("username","唐浩荣");
      //JSP方式获取session中的值
      String username = (String) session.getAttribute("username");
      //方式一
      out.println("JSP方式一获取:"+username);
  %>
  <br>
  <%--方式二--%>
  <%= "JSP方式二获取:"+ username%>

  <hr>
  <%--EL方式获取session中的值--%>
  EL方式获取:${username}

  </body>
</html>

运行结果如下:

image

两者相比,可以发现我们之前在JSP中写Java代码必须写在<% %>里面,并且取值代码比较繁琐。而EL表达式可以使我们的取值代码更加简洁方便。


EL表达式除了提供上面这种方式获取数据之外,还提供了其它两种运算符来存取数据:

  • 对象 . 属性
  • 对象[ "属性名" ]

其中 对象[ "属性名" ] 可以访问集合或者是数组的元素、Bean的属性,但是必须保证需要取得对象的那个属性有相对应的setXxx和getXxx方法才行,因为它是根据setXxx和getXxx方法来获取的,你可以【Ctrl+鼠标左键】选中属性试一试。下面是这两种EL表达式的使用举例:

①、对象 . 属性的使用:

${sessionScope.user.username}
//等价于
${sessionScope.user["username"]}

②、对象[ "属性名" ] 的使用(点和[ ] 可以混合使用)

${sessionScope.user[0].username}

2、EL表达式中的11个隐式对象

在上面看到的sessionScope是EL表达式提供的隐含对象,大家已经知道在JSP中有9个隐含对象(就是9个内置对象),而EL也有自己的隐含对象。EL隐含对象总共有11个(pageScope、requestScope、sessionScope、applicationScope、param 、paramValues、header、headerValues、initParam、cookie、pageContext),不过我们只简单看以下这四个:

EL隐含对象 作用 JSP对象
pageScope 获取pageContext域对象中的数据 pageContext
requestScope 获取request域对象中的数据 request
sessionScope 获取session域对象中的数据 session
applicationScope 获取application域对象中的数据 application

在EL表达式从这四个域中获得某个值的格式为:${xxxScope.key};等价于<%xxx.getAttribute(“username”)%>。而如果我们不指定作用域,直接${username}的话,默认会按照作用域的范围从小到大(page->request->session->application)依次查找,直到找到application为止。如果四个作用域中都没有则返回空字符串(注意:不是null,而是" "),然后什么都不显示。


补充:param和paramValues

①、param的作用:获取请求中的参数,格式:${param.请求参数名},等价于:request.getParameter("请求参数名")

②、paramValues的作用:获取多个同名的请求参数,格式:${paramValues.请求参数名},等价于request.getParameterValues("请求参数名"),例如:

<a href="${pageContext.request.contextPath}/testParam.jsp?username=admin&hobby=a&hobby=b">testParam.jsp</a>

username:${param.username}<br>
hobby:${paramValues.hobby[0]},${paramValues.hobby[1]}

2、EL表达式的运算

EL的运算符和Java中的运算符基本一致,优先级也相同,但是加号(+)运算符不再是连接了,而是真正的加法运算。

①、四则运算符

四则运算符 说明 举例 结果
+ ${5+5} 10
- ${5-5} 0
* ${5*5} 25
÷ ${5÷5} 1.0

②、关系运算符

关系运算符 说明 举例 结果
== 或 eq 等于 ${5==5}或${5 eq 5} true
!= 或 ne 不等于 ${5!=5}或${5 ne 5} false
< 或 lt 小于 ${3<5}或${3 lt 5} true
> 或 gt 大于 ${3>5}或${3 gt 5} false
<= 或 le 小于等于 ${3<=5}或${3 le 5} true
>= 或 ge 大于等于 ${3>=5}或${3 ge 5} false

③、逻辑运算符

逻辑运算符 说明 示例 结果
&& 或 and 交集 ${A && B}或${A and B} true/false
|| 或 or 并集 `${A
! 或 not ${!A}或${not A} true/false

④、empty运算符

该运算用来来检查对象是否为null(空),例如:${empty A}或者${!empty A}

在默认使用empty(不是!empty)的情况下:

  • 如果A为null时,返回true,否则返回false。
  • 如果A不存在时,返回true,否则返回false。
  • 如果A为空字符串时,返回true,否则返回false。
  • 如果A为空数组时,返回true,否则返回false。
  • 如果A为空的Map时,返回true,否则返回false。
  • 如果A为空的Collection时,返回true,否则返回false。

⑤、三元表达式

三元表达式格式为:${user!=null?user.username :" "}。如果?前面结果为true则选择前面的数据,否则选择后面的。

3、JSTL表达式介绍

JSTL标签库(JavaSeverPages Standard Tag Libary)的使用是为弥补HTML标签的不足,规范自定义标签的使用而诞生的。使用JSLT标签的目的就是不希望在JSP页面中出现Java逻辑代码。所以说它和EL一样,也是为了简化我们的JSP代码。JSTL一般与EL表达式结合使用,其中EL表达式多用于取值操作,而JSTL则可以方便我们对集合进行遍历,对数据进行判断等操作。

JSTL标签库可分为5类:

  • 核心标签(用得最多)
  • 格式化标签(I18N,日期等格式化标签)
  • SQL标签(SQL标签,很少使用)
  • XML标签(几乎不用)
  • JSTL函数(EL函数)

JSTL的核心标签库标签共14个,这些标签能够完成JSP页面的基本功能,减少编码工作。从功能上可以分为4类:表达式控制标签、流程控制标签、循环标签、URL操作标签。

  1. 表达式控制标签:out标签、set标签、remove标签、catch标签。
  2. 流程控制标签:if标签、choose标签、when标签、otherwise标签。
  3. 循环标签:forEach标签、forTokens标签。
  4. URL操作标签:import标签、url标签、redirect标签、param标签。

GIF 2020-4-29 21-35-18

首先要使用JSTL就得先下载并且导入相应的包。首先打开这个网站:Standard Taglib。然后选择最新版的JSTL,点击download

image

可以发现目前最新版本是1.2.5,将下面前两个jar包下载后导入到项目中即可。不会的可以参考这篇博客:IDEA创建一个JavaWeb项目

image

注意:我们必须要把下载的前两个包拷贝粘贴进WEB-INF下的lib目录中,通过Project Structure(Idea的操作)确保jar包已经引入,否则我们JSTL标签会报错,甚至是JSP访问不了或者报500报错。

然后我们在JSP页面添加标签的引用就可以使用JSTL标签了。引入JSTL的核心标签库如下:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • uri:指定引入的标签库的路径
  • prefix:设置标签库中标签的前缀,解决标签重名的问题

当然此时也可以发现其他的标签库:

image

引入格式如下所示:

<%--JSTL 核心标签--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--JSTL 格式化标签--%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%--JSTL SQL标签--%>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%--JSTL XMLb标签--%>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<%--JSTL 函数标签--%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

由于核心标签是使用最多的,所以只介绍核心标签库的使用,而且只介绍常用的。

4、JSTL的核心标签库

4.1、普通标签

①、<c:out>标签:用于将结果输出。类似于JSP中的<%= %>表达式,或者是EL表达式$\ expression }。

<%--取值--%>
<c:out value="${userName}"></c:out>

内部属性介绍:

  • value:设置要输出到页面的数据,要使用EL表达式
  • default:设置一个默认值,当value所设置的EL表达式的值为null时,则将default所对应的值输出到页面
  • escapeXml:设置输出到页面中的内容是否转义,默认值为true,表示转义,即原样输出;若设置为false,表示不转义,输出到页面中的内容会被浏览器解析

②、<c:set>标签:用于把某一个对象存在指定的域范围内,或者将某一个对象存储到Map或者JavaBean对象中。

<%--设值--%>
<c:set var="userName" value="tanghaorong" scope="session"></c:set>

内部属性介绍:

  • var:设置共享数据的属性名
  • value:设置共享数据的属性值
  • scope:设置共享数据的域对象的范围,若不指定域对象的范围,则默认在pageContext域对象中共享数据,scope="page(默认)|request|session|application"

③、<c:remove>标签:相较于<c:set>,作用是移除范围域中的变量。

<%--删除userName变量--%>
<c:remove var="userName"></c:remove>

内部属性介绍:

  • var:要删除的域对象中共享数据的属性名
  • scope:要删除共享数据的域对象的范围,
  • scope="page|request|session|application",若不指定scope,则删除所有域对象中以var的值作为属性名的数据

④、<c:catch>标签:用于捕获在嵌套在标签体中的内容抛出的异常,并将异常信息保存到变量中。

<c:catch var="exception">
  int i=5/0;
</c:catch>

<c:out value="${exception}"/>
<%--此句相当于exception.getMessage--%>
<c:out value="${exception.message}"/>

如果嵌套的代码出现异常,异常对象会被捕获,并且保持到var变量中,该变量总是有page范围,如果没有发生异常,则var所表示的范围变量将移除。而如果没有指定var属性,异常只是被简单捕获,但异常信息不会被保存。

4.2、条件标签(重要)

①、<c:if>标签:和程序中的if语句作用相同,用来实现条件控制,但是没else功能。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>JSTL的if标签示例</title>
</head>
<body>
<%
    //在session中设置值
    session.setAttribute("score",70);
%>

<c:if test="${score>60}">
    <span>恭喜!及格了</span>
</c:if>

</body>
</html>

若为条件为true,则打印中间的数据,当然我们也可以使用var变量来声明。

<c:if test="testCondition" [var="varName"] [scope="{page|request|session|application}"]>
       标签体内容
</c:if>

其中参数说明:

  1. test属性用于存放判断的条件,一般使用EL表达式来编写。
  2. var属性用来存放判断的结果,类型为true或false。
  3. scopes属性用来指定var属性存放的范围。

②、<c:choose>、<c:when>和<c:otherwise>标签:这三个标签通常一起使用,<c:choose>标签作为<c:when>和<c:otherwise>标签的父标签来使用。类似于程序中if-else,其中<c:when>表示if,<c:otherwise>表else。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>JSTL的if-else标签示例</title>
</head>
<body>
<%
    //在session中设置值
    session.setAttribute("score",50);
%>

<c:choose>
    <c:when test="${score>60}">
        <span>恭喜!及格了</span>
    </c:when>
    <c:otherwise>
        <span>不好意思!不及格</span>
    </c:otherwise>
</c:choose>

</body>
</html>

4.3、循环标签(非常重要)

①、<c:forEach>标签:该标签根据循环条件遍历集合(Collection)中的元素。

<c:forEach>标签的语法:

 <c:forEach
      var=”name”
      items=”Collection”
      [varStatus=”StatusName”]
      [begin=”begin”]
      [end=”end”]
      [step=”step”]>

    主体内容

</c:forEach>

其中参数说明:

  • var设定变量名用于存储从集合中取出元素。
  • items指定要遍历的集合。
  • varStatus设定变量名,该变量用于存放集合中元素的信息。其中varStatus有4个状态:index:当前循环的索引值、count:环的次数、frist:否为第一个位置、last:否为最后一个位置。
  • begin、end用于指定遍历的起始位置和终止位置(可选),默认下标从0开始。
  • step指定循环的步长,默认值为1。

forEach标签迭代集合举例(需要创建一个User,其中就两个属性,userName和age):

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.thr.User" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML>
<html>
<head>
    <title>JSTL的迭代标签示例</title>
</head>
<body>
<%
    List<User> users = new ArrayList<>();
    users.add(0,new User("张三",20));
    users.add(1,new User("李四",21));
    users.add(2,new User("王五",22));
    users.add(3,new User("赵六",23));
    users.add(4,new User("孙七",24));
    users.add(5,new User("周八",25));
    users.add(6,new User("吴九",26));
    users.add(7,new User("郑十",27));
    //在session中设置值
    session.setAttribute("users",users);
%>

<c:out value="输出整个迭代的信息:"/><br>
<c:forEach var="user" items="${users}" varStatus="userS">
    <span>姓名:${user.userName}--年龄:${user.age}</span><br>
</c:forEach>
<br><br><br><br>

<c:out value="输出其它属性信息:"/><br>
<c:forEach var="user" items="${users}" varStatus="userStatus" begin="4" end="6" step="1">
    <hr>
    计数:${userStatus.count} <br>
    步长:${userStatus.step} <br>
    开始位置: ${userStatus.begin} <br>
    结束位置:${userStatus.end} <br>
    下标:${userStatus.index} <br>
    是否是第一个:${userStatus.first} <br>
    是否是最后一个:${userStatus.last}<br>
</c:forEach>

</body>
</html>

②、<c:forTokens>标签:该标签用于浏览字符串,并根据指定的字符将字符串截取。

<c:forTokens>标签的语法:

<c:forTokens items=”strigOfTokens”
             delims=”delimiters”
            [var=”name”]
            [begin=”begin”]
            [end=”end”]
            [step=”len”]
            [varStatus=”statusName”] >

    主体内容

</c:forTokens>

其中参数说明:

  • items指定被迭代的字符串。
  • delims指定使用的分隔符。
  • var指定用来存放遍历到的成员。
  • begin指定遍历的开始位置(int型从取值0开始)。
  • end指定遍历结束的位置(int型,默认集合中最后一个元素)。
  • step遍历的步长(大于0的整型)。
  • varStatus存放遍历到的成员的状态信息。

forTokens使用范例:

<%@ page language="java" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html>
<head>
    <title>JSTL的forTokens标签实例</title>
</head>

<body>

<c:out value="根据一个分隔符截取:"/><hr>
<c:forTokens items="123-4567-8910" delims="-" var="tel">
    <c:out value="${tel}"></c:out><br/>
</c:forTokens>

<br/><br/><br/>

<c:out value="根据多个分隔符截取:"/><hr>
<c:forTokens var="str" items="太阳、星星、月亮;地球|火星" delims="、;|">
    <c:out value="${str}"></c:out><br/>
</c:forTokens>

<br/><br/><br/>

<c:out value="输出其它属性信息:"/><br><hr>
<c:forTokens items="1*2*3*4*5*6*7"
             delims="*"
             begin="1"
             end="3"
             var="n"
             varStatus="s">

    数字 <c:out value="${n}"/> 的四种属性:<br>
    所在位置,即索引:<c:out value="${s.index}"/><br>
    总共已迭代的次数:<c:out value="${s.count}"/><br>
    是否为第一个位置:<c:out value="${s.first}"/><br>
    是否为最后一个位置:<c:out value="${s.last}"/><br>
    <hr>
</c:forTokens>
</body>
</html>

注意:如果未设定截取分隔符(即delims属性未设置值)或在字符串中没有找到匹配的分隔符,那么在显示的时候会除去匹配的分隔符,而未匹配的则会继续在页面中显示。

posted @ 2020-04-27 17:43  唐浩荣  阅读(2780)  评论(0编辑  收藏  举报