文章目录
EL表达式
EL工具包介绍:
- 由Apache基金会使用Java命令开发的一个工具包
- 所有的HTTP服务器在出厂时都会自带EL工具包(Tomcat/lib/el-api.jar)
- 采用表达式编程风格,快速将作用域中共享数据读取并写入到响应体,用于简化JSP中Java命令开发步骤
EL表达式:
- 格式: ${作用域对象别名.共享数据名}
- 作用: 从指定的作用域对象得到指定共享数据,然后自动的将共享数据写入到响应体
EL表达式作用域对象别名
- jsp文件可以使用的作用域对象
application:全局作用域对象
session:会话作用域对象
request:请求作用域对象
pageContext:当前页作用域对象;存放的数据仅限当前JSP文件使用,JSTL工具包有相当数量的【Java标签工具类】,执行结果会自动写入到pageContext.,开发人员为了读取结果,就不得不从pageContext拿数据 - EL表达式作用域对象别名:
JSP文件 EL表达式
application appliationScope
session sessionScope
request requestScope
pageContext pageScope
EL表达式工作原理
${作用域对象别名.共享数据名.属性名}
从指定的作用域对象读取到指定共享数据。这个共享数据应该是一个高级类型对象。然后将高级类型对象属性内容读取并写入到响应体
原理:EL表达式定位到对象的属性名之后,调用属性对应的get方法读取属性内容。因此通过EL表达式读取的每一个属性必须都拥有 对应get方法
EL表达式支持表达式运算
- 前提: 从作用域对象读取到共享数据后,往往进行一个运算处理。然后将运算结果写入到响应体。EL表达式允许开发人员在得到共享数据后,对数据进行相关运算处理,然后将处理结果写入到响应体
- EL表达式支持哪些运算处理:
- ) 数学运算: + - * / %
- ) 关系运算: > >= < <= == !=
gt ge lt le eq != - ) 逻辑运算: && || !
EL表达式简化版
- 格式: ${共享数据名}
- 工作原理: 作用范围全靠猜
由于在简化版没有指定作用域对象。EL表达式采用【猜测】方式。
顺序 pageContext----> request ------>session----->application—>null - 存在的问题:
- 容易导致数据定位错误
- 容易导致程序运行速度下降
- 适用场景: 简化版就是为了从pageContext读取数据来研发
EL表达式其他工具对象
- param:
1[格式]: ${param.请求参数名}
2[作用]: 读取请求包中参数内容,然后将参数内容写入到响应体
3[代替]: <% String value = request.getParameter(“请求参数名”);
out.print(value);
%> - pageContext:
1[格式]: ${pageContext.jsp文件内置对象名.属性名}
2[作用]: 通过JSP文件的当前页作用域对象得到JSP文件中指定的内置对象的属性内容。然后将属性内容写入到响应体
EL工具包缺陷:
- 只能从作用域对象读取共享数据。但是不能向作用域对象写入共享数据
- 不提供控制语句操作【if…else… 循环遍历】
*****单独在JSP文件上使用EL表达式,不能取代所有的Java命令
JSTL表达式
JSTL工具包:
- 由sun公司提供的一组jar包。采用Java技术来实现
- 专门在JSP文件开发时使用,用于替代JSP文件上所有的Java命令
- 提供的【工具类/命令】。是以标签形式出现。看起来就像HTML标签
如何在项目使用JSTL工具包
- 手动将【jstl.jar 与 stanrad.jar】加载到项目/web/WEB-INF/lib中
- 在JSP文件上引入JSTL工具中命令关联的配置文件编号
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
四个JSTL标签命令介绍:
<c:set/>
- 作用:在JSP文件上,对四个作用域对象内容进行写入与修改的
- 格式:<c:set scope=“操作作用域对象别名” var=“共享数据名” value=“共享数据”/>
- 属性: scope:指向本次操作的【作用域对象别名】
cope=“application/session/request/page”
var: 声明共享数据名称
value: 共享数据 - 代替:
任务:在当前的JSP文件上,将共享数据【userAge=10】写入到request作用域对象
<%
request.setAttribute("userAage",10);
%>
<c:set scope="request" var="userAge" value="10"/>
<c:if></c:if>
- 作用: 在JSP文件上,根据实际情况决定是否要将指定的内容写入到响应体
- 格式:
<c:if test="判断结果">
输出内容
</c:if>
- 属性:
test: 接收运算表达式返回结果,这个结果为true,将<c:if></c:if>中【输出内容】写入到响应体
这个结果为false.此时<c:if></c:if>中【输出内容】将不会写入到响应体 - 代替:
任务:在JSP文件上,根据用户年龄决定是否输出"欢迎光临"四个字
<%
int age=20;
if(age >= 18){
out.print("欢迎光临")
}
%>
<c:choose></c:choose>
- 作用: 在JSP文件上,通过【多分枝选择判断(if…else if…else if…else)】方式决定在当前情况下,是否可以将某个内容写入到响应体
- 格式:
<c:choose>
<c:when test="判断结果">输出内容1</c:when>
<c:when test="判断结果">输出内容2</c:when>
<c:when test="判断结果">输出内容3</c:when>
<c:otherwrise>输出内容4</c:otherwrise>
</c:choose>
- 参数:
一个<c:when></c:when>
相当于一个判断分支(if/else if)
在<c:choose></c:choose>
标签允许出现多个<c:when></c:when>
<c:otherwrise></c:otherwrise>
只能出现在<c:choose></c:choose>
最后一行,一个<c:choose></c:choose>
之多只能出现一个<c:choose></c:choose>
<c:otherwrise></c:otherwrise>
在上面所有<c:when>
都不能得到true情况下才会被调用 - 代替:
任务:在JSP文件根据用户年龄判断用户属于【老年人,中年人,青年人】
<%
int age = 22;
if(age >= 60){
out.print("老年人")
}else if(age>=40){
out.print("中年人");
}else{
out.print("年轻人")
}
%>
<c:forEach></c:forEach>
- 作用: 在JSP文件上,循环遍历方式将内容写入到响应体
- 格式:
场景1:在指定循环次数的情况下,循环遍历输出
<c:forEach var="声明循环变量名称" begin="设置循环变量初始值" end="设置循环变量接收最大值,超过这个值循环立刻结束"
step="设置每次循环后,循环变量递增的值或则递减值">
循环输出内容
</c:forEach>
**** forEach标签自动的将循环变量保存到当前页作用域对象作为共享数据${pageScope.循环变量名}
**** step属性可以不声明。默认值每次递增加一。
场景2:从作用域对象读取集合,通过循环遍历方式将集合中对象内容读取并写入到响应体
<c:forEach items="指向遍历的集合" var="声明循环变量,每次循环时从集合得到一个对象交给循环变量管理"
varStatus="声明循环计数器变量,每次循环时循环计数器的值递增加一">
循环体
</c:forEach>
例如:
<c:forEach items="${dtlist}" var="list" varStatus="i" >
<tr>
<td><input type="checkbox" /></td>
<td>${i.count}</td>
<td>${list.code}</td>
<td>${list.name}</td>
<td>${list.description}</td>
</tr>
</c:forEach>
**** 在jsp文件上,所有从作用域读取的集合,一定是通过Servlet存储到集合中,因此 items="${作用域对象别名.共享数据名}"
var与varStatus声明循环变量与循环计数器都是被自动保存在当前页作用域对象作为共享数据
循环计数器变量在声明时自动拥有count属性,这个属性用于记录当前循环次数。varStatus可以不声明