正文
JavaEE-08 JSTL和EL
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
学习要点- EL表达式
- JSTL标签
EL表达式为什么需要EL表达式
- JavaBean在JSP中的局限
- 在JSP页面中嵌入大量的Java代码
- 获取JavaBean属性必须要实例化
- 强制类型转化
为什么需要EL表达式
- JavaBean在JSP中的局限
- 在JSP页面中嵌入大量的Java代码
- 获取JavaBean属性必须要实例化
- 强制类型转化
例如,Computer类是Employee类中的一个属性,现在要获取员工计算机制作商信息,则需要编写如下代码:
<%
Employee employee = (Employee) request.getAttribute("employee");
Computer comp = employee.getComputer();
String manufacturer = comp.getManufacturer();
%>
- 解决办法
JSP2.0引入了EL表示式,简化如下:
${requestScope.employee.computer.manufacturer}
EL表达式
EL:Expression Language(表达式语言)
EL的功能:替代JSP页面中的复杂代码
EL的特点:能够自动转换类型(EL得到某个数据时可以自动转换类型);使用简单;定义了一系列隐含对象和操作符,方便访问页面的上下文,以及不同作用域的对象。
EL表达式语法结构
语法:
${ EL exprission }
用于:使用变量名获取值、获取对象的属性值、获取集合
- 使用变量名获取值
${变量名}
<% request.setAttribute("username","LiYang"); %>
姓名: ${requstScope.username}
变量属性范围名称
属性范围 | EL中的名称 |
page | pageScope,例如${pageScope.username},表示在page范围内查找username变量,找不到返回Null |
request | requstScope |
session | sessionScope |
application | applicationScope |
使用EL表达式访问某个属性值时,应该指定查找的范围,例如${requstScope.username},即在request请求域查找属性名为username的属性值。如果不指定查找范围,则系统会按照page -> request -> session -> application作用域的顺序查找。
- 获取对象的属性值
点操作符:${user.name}
[ ]操作符:${user["name"]}
相当于:
<%
User user = (User )request.getAttribute("user");
user.getName();
%>
- 获取集合
获取List集合
<%
List names = new ArrayList();
names.add(0, "LiYang");
names.add(1,"WangHua");
request.setAttribute("names",names);
%>
姓名:${names[0]}<br/>
姓名:${names[1]}<br/>
问题:nams[0]和names[1]两个变量的属性范围名称是?
获取Map集合
<%
Map names = new HashMap();
names.put("one", "LiYang");
names.put("two", "WangHua");
request.setAttribute("names", names);
%>
姓名:${names.one}<br />
姓名:${names["two"]}<br />
- 关系操作符
关系操作符 | 说明 | 示例 | 结果 |
==(或eq) | 等于 | ${23==5}或${23 eq 5} ${"a" =="a"}或${"a" eq "a"} | false true |
!=(或ne) | 不等于 | ${23!=5}或${23 ne 5} | true |
<(或lt) | 小于 | ${23<5}或${23 lt 5} | false |
>(或gt) | 大于 | ${23>5}或${23 gt 5} | true |
<=(或le) | 小于等于 | ${23<=5}或${23 le 5} | false |
>=(或ge) | 大于等于 | ${23>=5}或${23 ge 5} | ture |
- 逻辑操作符
逻辑操作符 | 说明 | 示例 | 结果 |
&&(或and) | 逻辑与 | 如果A为true,B为false,则A&&B(或A and B) | false |
||(或or) | 逻辑或 | 如果A为true,B为false,则A||B(或A or B) | true |
! (或not) | 逻辑非 | 如果A为true,则!A (或not A) | false |
- Empty操作符
变量 a不存在,则${empty a}返回的结果为true
${not empty a}或${!empty a}返回的结果为false
EL隐式对象
隐式对象介绍
对象名称 | 说 明 |
pageScope | 返回页面范围的变量名,这些名称已映射至相应的值 |
requestScope | 返回请求范围的变量名,这些名称已映射至相应的值 |
sessionScope | 返回会话范围的变量名,这些名称已映射至相应的值 |
applicationScope | 返回应用范围内的变量,并将变量名映射至相应的值 |
param | 返回客户端的请求参数的字符串值 |
paramValues | 返回映射至客户端的请求参数的一组值 |
pageContext | 提供对用户请求和页面信息的访问 |
EL表达式的综合应用
- 注册页面代码
<form id="regFrm" action="regSuccess.jsp" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input id="userName" name="userName" type="text"></td>
</tr>
<tr>
<td>密码:</td>
<td><input id="password" name="password" type="password"></td>
</tr>
<tr>
<td>业余爱好:</td>
<td>
<input name="habit" type="checkbox" value="Reading">看书
<input name="habit" type="checkbox" value="Game">玩游戏
<input name="habit" type="checkbox" value="Travelling">旅游
<input name="habit" type="checkbox" value="Swimming">游泳
<input name="habit" type="checkbox" value="TV">看电视
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
- 注册信息处理页代码
<%
request.setCharacterEncoding("UTF-8");
//从请求参数中取得用户名
String userName = request.getParameter("userName");
//密码
String password = request.getParameter("password");
//业余爱好
String[] habits = request.getParameterValues("habit");
//此处生成一个User对象,以便展示EL访问某个作用域内的对象
User user = new User();
user.setName(userName);
user.setPassword(password);
user.setHabits(habits);
//把此user对象设置为request范围内的一个属性
request.setAttribute("userObj", user);
%>
====使用request作用域内的userObj对象展示注册信息====
<br> 注册成功,您的注册信息是:
<br> 用户名:${requestScope.userObj.name }
<br> 业余爱好:<%
for (int i = 0; i < habits.length; i++) {
if (i > 0) {
out.print("、");
}
out.print(habits[i]);
}
%>
<br>
<br>
<br>
<br> ====使用param对象与paramValues对象展示注册信息====
<br> 用户名:${param.userName }
<br> 业余爱好:<%
for (int i = 0; i < habits.length; i++) {
if (i > 0) {
out.print("、");
}
request.setAttribute("i", i); //将索引放到请求域中
%>
${paramValues.habit[i]}
<%
}
%>
- User类
public class User {
private String name;
private String password;
private String[] habits;
//...
}
上机练习
需求说明
- 用户输入昵称、所在城市,并且以多选的方式让用户选择所使用的开发语言,然后使用EL表达式显示在页面上
- 昵称和所在城市使用param对象输出
JSTL使用JSTL的原因
虽然EL表达式可以访问JavaBean的属性,但是并不能实现在JSP中进行逻辑判断,因而要使用JSTL标签。
JSTL概念
JSP标准标签库(JavaServerPages Standard Tag Library)。
JSTL通常会与EL表达式合作实现JSP页面的编码。
JSTL 的优点:提供一组标准标签;可用于编写各种动态 JSP 页面。
JSTL的环境搭建
- 在工程中引用JSTL的两个jar包和标签库描述符文件
如果采用myeclipse创建项目,选择了JavaEE 6.0或者JavaEE 5.0,则自动集成了JSTL
- 在JSP页面添加taglib指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- 使用JSTL标签
JSTL标准标签库内的标签核心标签库
通用标签
- set标签
说明:设置指定范围内的变量值
1.将value值存储到范围为scope的变量variable中
语法格式:
<c:set var="variable" value=" v " scope=" scope "/>
实例代码:
<c:set var="index" value=" 110 " scope="request"/>
2.将value值设置到对象的属性中
语法格式:
<c:set value="value" target="target" property="property" />
示例代码:
<%
User user = new User();
request.setAttribute("user", user);
%>
<c:set target="${user}" property="name" value="张三"/>
- out标签
说明:计算表达式并将结果输出显示
语法格式:
1.不指定默认值:
<c:out value="value" />
2.指定默认值:
<c:out value="value" default="default" />
示例代码:
<%
User user = new User();
request.setAttribute("user", user);
%>
<c:set target="${user}" property="name" value="defaultName " />
<c:out value="${user.name}" default="noUserName" />
类似于JSP中的<%=%>,它可以指定默认值,比<%=%>强大。默认值可以方便的处理空值情况。
- 转义特殊字符
<p>${"<a href='http://www.baidu.com'>百度</a>"}</p>
<p><c:out escapeXml="false" value="<a href='http://www.baidu.com'>百度</a>"/></p>
<c:out value="<a href='http://www.baidu.com'>百度</a>" />
输出效果
属性说明
属性 | 描述 | 是否必要 | 默认值 |
value | 要输出的内容 | 是 | 无 |
default | 输出的默认值 | 否 | 主体中的内容 |
escapeXml | 是否忽略XML特殊字符 | 否 | true |
- remove标签
说明:删除指定范围内的变量
示例代码:
<!-- 设置之前应该是空值 -->
设置变量之前的值是:msg=
<c:out value="${msg}" default="null" />
<!-- 给变量msg设值 -->
<c:set var="msg" value="Hello JSP!" scope="page"></c:set>
<!-- 此时msg的值应该是上面设置的"已经不是空值了" -->
<br>设置新值以后:msg=
<c:out value="${msg}"></c:out>
<!-- 把 msg变量从page范围内移除-->
<c:remove var="msg" scope="page" />
<!-- 此时msg的值应该显示null -->
<br>移除变量msg以后:msg=
<c:out value="${msg}" default="null"></c:out>
条件标签
- if标签
说明:实现Java语言中if语句的功能
语法格式:
<c:if test="<boolean>" var="<string>" scope="<string>">
...
</c:if>
参数说明:
属性 | 描述 | 是否必要 | 默认值 |
test | 条件 | 是 | 无 |
var | 用于存储条件结果的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | page |
示例代码:
User用户实体类:
/**User类*/
public class User {
private String name;
private String password;
private String role;
private String[] habits;
//……
}
login.jsp页面关键代码:
/**login.jsp*/<%
String userName = request.getParameter("userName");//用户名
String password = request.getParameter("passWord");//密码
String cmdStr = request.getParameter("cmdStr");//cmdStr
if ("post".equals(cmdStr)) {
if ("admin".equals(userName) && "admin".equals(password)) {
//登录成功
User user = new User();
user.setName(userName);
user.setPassword(password);
//设置session属性
request.getSession().setAttribute("user", user);
} else {
request.setAttribute("errMsg", "用户名或密码不正确");
}
}
%>
<c:set var="isLogin" value="${empty sessionScope.user}" />
<c:if test="${isLogin}">
<form id="login" method="post" action="login_2.jsp">
<input type="hidden" value="post" name="cmdStr">
<c:if test="${not empty errMsg}">
<div style="color:red;">${errMsg}</div>
<c:remove var="errMsg" />
</c:if>
<table>
<tr>
<td>用户名:</td>
<td><input id="userName" name="userName" type="text"></td>
</tr>
<tr>
<td>密码:</td>
<td><input id="passWord" name="passWord"
type="password"></td>
</tr>
</table>
<input type="submit" value="登录">
</form>
</c:if>
<c:if test="${!isLogin}">
欢迎 ${user.name},您已经登录成功!
<c:remove var="user" scope="session"/>
</c:if>
- choose标签
说明:实现Java语言中if-else if-else语句的功能。
语法结构:
<c:choose >
<c:when test="<boolean>"/>
...
</c:when>
<c:when test="<boolean>"/>
...
</c:when>
...
...
<c:otherwise>
...
</c:otherwise>
</c:choose>
示例代码1:简单判断
<c:set var="salary" scope="session" value="${2000*2}" />
<p>
你的工资为 :
<c:out value="${salary}" />
</p>
<c:choose>
<c:when test="${salary <= 0}">
太惨了。
</c:when>
<c:when test="${salary > 1000}">
不错的薪水,还能生活。
</c:when>
<c:otherwise>
什么都没有。
</c:otherwise>
</c:choose>
示例代码2:角色页面
<%
//用户名
String userName = request.getParameter("userName");
//密码
String password = request.getParameter("passWord");
//cmdStr
String cmdStr = request.getParameter("cmdStr");if ("post".equals(cmdStr)) {
if ("accp_user".equals(userName) && "accp_pass".equals(password)) {
//登录成功
User user = new User();
user.setName(userName);
user.setPassword(password);
user.setRole("部门经理");
//设置session属性
request.getSession().setAttribute("user", user);
} else {
request.setAttribute("errMsg", "用户名或密码不正确");
}
}
%>
<c:choose>
<c:when test="${empty user}">
<form id="login" method="post" action="login_3.jsp">
<input type="hidden" value="post" name="cmdStr">
<c:if test="${not empty errMsg}">
<div style="color:red;">${errMsg}</div>
<c:remove var="errMsg" />
</c:if>
<table>
<tr>
<td>用户名:</td>
<td><input id="userName" name="userName"
type="text"></td>
</tr>
<tr>
<td>密码:</td>
<td><input id="passWord" name="passWord"
type="password"></td>
</tr>
</table>
<input type="submit" value="登录">
</form>
</c:when>
<c:otherwise>
<c:choose>
<c:when test="${user.role eq '总监'}">
总监页面
</c:when>
<c:when test="${user.role eq '部门经理'}">
部门经理页面
</c:when>
<c:otherwise>
员工页面
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
迭代标签
forEach标签:实现对集合中对象的遍历
语法结构:
<c:forEach items="<object>" begin="<int>" end="<int>" step="<int>"
var="<string>" varStatus="<string>">
//循环体
</c:forEach>
参数说明:
属性 | 描述 | 是否必要 | 默认值 |
items | 要被循环的信息 | 否 | 无 |
begin | 开始的元素(0=第一个元素,1=第二个元素) | 否 | 0 |
end | 最后一个元素(0=第一个元素,1=第二个元素) | 否 | Last element |
step | 每一次迭代的步长 | 否 | 1 |
var | 代表当前条目的变量名称 | 否 | 无 |
varStatus | 代表循环状态的变量名称 | 否 | 无 |
使用方法:
forEach是for循环语句的变体,实现集合对象(可以是list、数组等)的处理。
示例代码1:输出循环变量
<c:forEach var="i" begin="1" end="5">
Item<c:out value="${i}"/><p>
</c:forEach>
示例代码2:按照指定步长输出信息
<c:forEach begin="1" end="5" step= "2">
<c:out value="*"></c:out>
</c:forEach>
示例代码3:遍历Map集合
<%
Map<String, String> map = new HashMap<String, String>();
map.put("tom", "美国");
map.put("lily", "英国");
map.put("jack", "中国");
request.setAttribute("map", map);
%>
<c:forEach var="entry" items="${map}">
${entry.key}
${entry.value}<p>
</c:forEach>
示例代码4:遍历List集合
<%
List products = GoodsDao.getAllProducts();
request.setAttribute("products", products);
%>
<!-- 循环输出商品信息 -->
<c:forEach var="product" items="${requestScope.products}" varStatus="status">
<!-- 如果是偶数行,为该行换背景颜色 -->
<tr <c:if test="${status.index % 2 == 1}">style="background-color:rgb(219,241,212);"</c:if>>
<td>${product.name }</td>
<td>${product.area }</td>
<td>${product.price }</td>
</tr>
</c:forEach>
上机练习
需求描述
- 使用EL表达式和JSTL标签简化新闻发布系统页面
总结- EL表达式的语法有两个要素:$ 和 {}
- EL表达式可以使用“.”或者“[]”操作符在相应的作用域中取得某个属性值
- JSTL核心标签库中常用的标签有如下三类。
通用标签;<c:set>、<c:out>、<c:remove>
条件标签;<c:if>、<c:choose>、<c:when>、<c:otherwise>
迭代标签:<c:forEach>
- EL表达式与JSTL标签结合使用,可以减少JSP中嵌入的Java代码,有利于程序的维护和扩展