学习要点
- EL表达式
- JSTL标签
EL表达式
为什么需要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代码,有利于程序的维护和扩展