1. EL 表达式
a) 什么是EL表达式,EL表达式的作用?
b) 什么是EL表达式,EL表达式的作用?
c) EL表达式搜索域数据的顺序
d) EL表达式输出Bean的普通属性,数组属性。List集合属性,map集合属性
e) EL表达式——运算
1)关系运算
2)逻辑运算
3)算数运算
i. empty运算
ii. 三元运算
iii. “.”点运算 和 [] 中括号运算符
f) EL表达式的11个隐含对象
i. EL获取四个特定域中的属性
ii. pageContext对象的使用
iii. EL表达式其他隐含对象的使用
2. JSTL 标签库
a) 什么是JSTL标签库
b) JSTL标签库的使用步骤
c) core核心库使用
i. <c:set />
ii. <c:if />
iii. <c:choose> <c:when> <c:otherwise>标签
iv. <c:forEach />
EL表达式& JSTL标签库
1. EL 表达式
a) 什么是EL表达式,EL表达式的作用?
EL的全称是Expression Language表达式语言。表达式语言是为了在jsp页面中替代表达式脚本而新生产的技术。
EL表达式可以代替表达式脚本在jsp页面中输出数据。因为EL表达式在jsp页面中输出数据的时候会比jsp的表达式脚本要简洁。
<body>
<%
request.setAttribute("abc", "requestData");
%>
jsp表达式脚本:<%=request.getAttribute("abc1") == null ? "" : request.getAttribute("abc1") %><br/>
EL表达式:${ abc1 }<br/>
</body>
1、EL表达式主要是输出域对象中的数据。
2、EL表达式在输出null值的时候,会动输出空串。而jsp表达式脚本在输出null值的时候,会输出null字符串。
EL表达式的语法:${ key }
b) EL表达式搜索域数据的顺序
当四个域中都同时存在有相同的key的域数据的时候。那么EL表达式会从小到大搜索四个域,只要找到就输出。
<body>
<%
// request.setAttribute("abc", "requestData");
// session.setAttribute("abc", "sessionData");
application.setAttribute("abc", "applicationData");
// pageContext.setAttribute("abc", "pageContextData");
%>
<%-- 传统jsp表达式脚本:<%=request.getAttribute("abc1") == null ? "" : request.getAttribute("abc1") %><br/> --%>
<%-- EL表达式:${ abc }<br/> --%>
${ abc }
</body>
c) EL表达式输出Bean的普通属性,数组属性。List集合属性,map集合属性
i. 如下:输出Person类中普通属性,数组属性。list集合属性和map集合属性。
Person对象
public class Person {
private String name;
// i.数组属性。list集合属性和map集合属性。
private String[] phones;
private List<String> list;
private Map<String, Object> map;
EL输出的测试代码:
<body>
<%
Person p = new Person();
p.setName("华仔");
p.setPhones(new String[]{"13988886666","13988886661","13988886662"});
List<String> list = new ArrayList<String>();
list.add("item1");
list.add("item2");
list.add("item3");
p.setList(list);
Map<String,Object> map = new HashMap<String,Object>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
p.setMap(map);
request.setAttribute("person", p);
%>
输出整个person对象:${ person }<br/>
输出name属性值:${ person.name }<br/>
输出数组元素值:${ person.phones[1] }<br/>
输出list集合的元素值:${ person.list[2] }<br/>
输出map集合的元素值:${ person.map.key1 }<br/>
</body>
常见错误

当我们在EL表达式中输出JavaBean对象属性数据的时候。
比如代码是:${ person.abc } 其实找到的是person 对应的Person对象。其实调用abc的读方法getAbc()或isAbc()
所以对象后面的值一定要和Bean的属性名一致
输出整个对象:${ key } 输出整个javaBean对象(输出整个value)。
输出数组元素:${ key.数组名[下标] }
输出list集合元素: ${ key.list集合变量名[下标] }
输出的是map集合元素:${ key.map对象变量名.mapKey值 }
d) EL表达式——运算
1)关系运算

2)逻辑运算

3)算数运算
i. empty运算
empty运算是判断一个数据是否为空,如果为空返回true。反之亦然。
1、如果值为null,结果为真。
2、如果值是空串,结果也为真。
3、如果值是Object数组,并且长度为零。结果也为真。
4、如果值是list集合,元素个数为零,结果也为真。
5、如果值是map集合,元素个数为零,结果也为真。
<body>
<%
// 1、如果值为null,结果为真。
request.setAttribute("abc", null);
// 2、如果值是空串,结果也为真。
request.setAttribute("emptyStr", "");
// 3、如果值是Object数组,并且长度为零。结果也为真。
request.setAttribute("emptyArr", new Object[]{});
// 4、如果值是list集合,元素个数为零,结果也为真。
List list = new ArrayList();
// list.add(1234);
request.setAttribute("emptyList", list);
// 5、如果值是map集合,元素个数为零,结果也为真。
Map map = new HashMap();
map.put("abc", "asdf");
request.setAttribute("emptyMap", map);
%>
${ empty abc }<br/>
${ empty emptyStr }<br/>
${ empty emptyArr }<br/>
${ empty emptyList }<br/>
${ empty emptyMap }<br/>
</body>
ii. 三元运算
${ 表达式1?表达式2:表达式3 }
如果表达式1为真,输出表达式2的值,如果表达式1为假,输出表达式3的值。
iii. “.”点运算 和 [] 中括号运算符
“.”点运算,可以用来输出javaBean对象的某个属性的值。也可以用来输出map对象的某个key的值。
[] 中括号运算,中括号运算可以输出有序集合中的元素值(通过下标)。
中括号运算,还可以输出map对象中,key里含特殊字符的key所对应的值(特殊字符,就是前面那些+,-,*,/等等运算符)
<body>
<%
Map<String,Object> map = new HashMap<String,Object>();
map.put("a.a.a", "aaaValue");
map.put("b+b+b", "bbbValue");
request.setAttribute("map", map);
%>
${ map['a.a.a'] }<br/>
${ map["b+b+b"] }<br/>
</body>
a) EL表达式的11个隐含对象
变量名 | 数据类型 | 作用 |
pageContext | PageContextImpl | 它可以获取到jsp的九大内置对象 |
pageScope | Map<String,Object> | 它可以获取到pageContext域中的数据 |
requestScope | Map<String,Object> | 它可以获取到request域中的数据 |
sessionScope | Map<String,Object> | 它可以获取到Session域中的数据 |
applicationScope | Map<String,Object> | 它可以获取到ServletContext域中的数据 |
param | Map<String,String> | 它可以获取到请求的参数值 |
paramValues | Map<String,String[]> | 它可以获取到请求的参数值(多个值) |
header | Map<String,String> | 它可以获取到请求头的值。 |
headerValues | Map<String,String[]> | 它可以获取到请求头的值(多个值) |
cookie | Map<String,Cookie> | 它可以获取到当前请求 Cookie的信息 |
initParam | Map<String,String> | 它可以获取到web.xml中配置<context-param> |
i. EL获取四个特定域中的属性
pageContext <========> pageScope
request <========> requestScope
session <========> sessionScope
ServletContext <========> applicationScope
<body>
<%
request.setAttribute("abc", "requestData");
session.setAttribute("abc", "sessionData");
application.setAttribute("abc", "applicationData");
pageContext.setAttribute("abc", "pageContextData");
%>
<%-- jsp表达式脚本:<%=request.getAttribute("abc1") == null ? "" : request.getAttribute("abc1") %><br/> --%>
<%-- EL表达式:${ abc1 }<br/> --%>
取域值最小的默认方式:${abc}
request域的单个值:${ requestScope.abc }<br/>
session域的单个值:${sessionScope.abc }<br/>
ServletContext域的单个值:${applicationScope.abc }<br/>
pageContext域的单个值:${pageScope.abc }<br/>
session域的所有值${ sessionScope }<br/>
</body>
ii. pageContext对象的使用
注意区分:
requestScope获取request域中的数据:request.setAttribute("mappp", map);
pageContext获取request域对象,通过该域对象获取request域的属性值:pageContext.setAttribute("req", request);
不过一般还是直接用pageContext.request.获取属性
<body>
<%
// 经常会把request域保存到域中,然后在EL中使用的时候会很简短
pageContext.setAttribute("req", request);
%>
1.协议:${ req.scheme } <br/>
2.服务器ip:${ pageContext.request.serverName } <br/>
3.服务器端口:${ pageContext.request.serverPort } <br/>
4.获取工程路径:${ pageContext.request.contextPath } <br/>
5.获取请求方法:${ pageContext.request.method } <br/>
6.获取客户端ip地址:${ pageContext.request.remoteHost } <br/>
7.获取会话的id编号:${ pageContext.session.id } <br/>
</body>
iii. EL表达式其他隐含对象的使用
:param,paramValues,header,headerValues,cookie,initParam
web.xml中配置:
<context-param>
<param-name>aaa</param-name>
<param-value>aaaValue</param-value>
</context-param>
<context-param>
<param-name>bbb</param-name>
<param-value>bbbValue</param-value>
</context-param>
测试的请求地址是:http://ip:port/工程名/el_other.jsp?a=avalue&bb=bbValue
<body>
${ param.bb }<br/>
${ paramValues.bb[0] }<br/>
<hr/>
${ header['user-agent'] }<br/>
${ headerValues['user-agent'][0] }<br/>
<hr/>
${ cookie.JSESSIONID.value }<br/>
${ initParam.aaa }
<hr/>
</body>
2. JSTL 标签库
a) 什么是JSTL标签库
JSTL标签库 全称是指 JSP Standard Tag Library JSP标准标签库。是一个不断完善的开放源代码的JSP标签库。
注:::
EL表达式主要是为了替换jsp中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个jsp页面变得更佳简洁。
Jsp三大脚本:声明脚本、表达式脚本(EL可替代)、代码脚本(JSTL可替代)
JSTL由五个不同功能的标签库组成。

在jsp标签库中使用taglib指令引入标签库
CORE 标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
XML 标签库
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
FMT 标签库
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
SQL 标签库
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
FUNCTIONS 标签库
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
b) JSTL标签库的使用步骤
1、先导入jar包
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
2、使用taglib指令引入你需要使用的标签库
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
c) core核心库使用
i. <c:set />
1、往域中保存数据
2、修改域中的javaBean对象的某个属性或修改域中map对象的某个key的值。
这里提一句:EL表达式主要作用:获取域中的值
1、往域中保存数据
(1)、传统域对象
域对象.setAttribute(key,value);
(2)、jstl标签库
c:set
参数:
scope:属性设置将数据保存到哪个目标域中
var:属性设置需要保存的数据的key
value:需要保存到域中的值
2、修改域中的JavaBean对象的某个属性或修改域中map对象的某个key的值
(1)、传统修改Bean
Javabean.setXxx(value);
、传统修改map,repalce()方法
(2)、jstl标签库
c:set
参数:
target:属性设置你要修改的目标域对象中(page,request,session,application),非(pageContext,servletContext)中
property:属性表示你要操作的JavaBean的属性名,或map对象的key值
value:需要保存到域中的值
<body>
<!-- 1、往域中保存数据
域对象.setAttribute(key,value);
c:set
scope 属性设置将数据保存到哪个域中
page(pageContext),request,session,application(servletContext) 默认是page
var 属性设置需要保存的数据的key
value 属性设置需要保存到域中的值
-->
set保存之前: ${ requestScope.abc }<br/>
<c:set scope="request" var="abc" value="abcVAlue"/>
set保存之后: ${ requestScope.abc }<br/>
<!-- 2、修改域中的javaBean对象的某个属性或修改域中map对象的某个key的值。
javaBean.setXxxxx(value);
map.put(key,value);
target属性表示你要操作的目标对象
property属性表示你要操作的javaBean的属性名,或map对象的key值
-->
<%
Map<String,Object>map = new HashMap<String,Object>();
map.put("aaa", "oldValue");
request.setAttribute("map", map);
%>
修改之前输出:${ map }<br/>
<c:set target="${ map }" property="aaa" value="newValue" />
修改之后输出:${ map }<br/>
</body>
set1保存之前:${pageScope.def}<br/>
<c:set scope="page" var="def" value="defvalue"/>
set1保存之后:${pageScope.def}<br/>
set2保存之前: ${ requestScope.abc }<br/>
<c:set scope="request" var="abc" value="abcVAlue"/>
set2保存之后: ${ requestScope.abc }<br/>
set3保存之前: ${ sessionScope.abc }<br/>
<c:set scope="session" var="abc" value="abcVAlue"/>
set3保存之后: ${ sessionScope.abc }<br/>
set4保存之前: ${ applicationScope.abc }<br/>
<c:set scope="ServletContext" var="abc" value="abcVAlue"/>
set4保存之后: ${ applicationScope.abc }<br/>
ii. <c:if />
相当 于 if 语句判断,是单路判断。
<!--
c:if做if判断。
test 属性是判断表达式的值。
-->
<c:if test="${ 12 == 12 }">
<h1>12等于12</h1>
</c:if>
iii. <c:choose> <c:when> <c:otherwise>标签
是多路判断,相当于switch-case-default
1、在这组标签中,不能使用html注释
2、c:when的父标签一定要是c:choose标签
<%
request.setAttribute("money", 9);
%>
<%--
c:choose-c:when-c:otherwise 使用需要注意
1、在这组标签中,不能使用html注释
2、c:when的父标签一定要是c:choose标签
c:choose多路判断
--%>
<c:choose>
<%-- c:when 当什么什么的时候,也就是一种情况下:
test 是判断的表达式
--%>
<c:when test="${ requestScope.money > 90 }">
<h1>富人</h1>
</c:when>
<c:when test="${ requestScope.money > 80 }">
<h2>中等阶级</h2>
</c:when>
<c:when test="${ requestScope.money > 60 }">
<h3>小康</h3>
</c:when>
<%-- otherwise 相当于default的情况 --%>
<c:otherwise>
<c:choose>
<c:when test="${ requestScope.money > 50 }"></c:when>
<c:when test="${ requestScope.money > 40 }"></c:when>
</c:choose>
</c:otherwise>
</c:choose>
iv. <c:forEach />
做遍历(循环)
<c:set/>保存---参数:target:属性设置你要修改的目标对象
(page,request,session,application),非(pageContext,servletContext)中
<c:set/>修改---参数:scope:属性设置将数据保存到哪个目标域对象中
<c:forEach/> 遍历---参数:items:设置遍历的目标数据源
创建Student对象
public class Student {
// 编号,用户名,密码,年龄,电话信息
private int id;
private String name;
private String password;
private int age;
private String phone;
public Student(int id, String name, String password, int age, String phone) {
super();
this.id = id;
this.name = name;
this.password = password;
this.age = age;
this.phone = phone;
}
forEach代码:
<body>
<!-- 1.遍历1到10,输出
begin 属性设置遍历(循环)的开始索引
end 属性设置遍历(循环)的结束索引
var 属性 当前正在遍历到的数据(循环变量)
-->
<c:forEach begin="1" end="10" var="i">
${ i }
</c:forEach>
<hr/>
<!-- 3.遍历Map集合 -->
<%
Map<String,Object> map = new HashMap<String,Object>();
map.put("aaa", "aaaValue");
map.put("bbb", "bbbValue");
map.put("ccc", "cccValue");
request.setAttribute("map", map);
%>
<%-- items 属性设置你要遍历的数据源 --%>
<c:forEach items="${ requestScope.map }" var="entry">
${ entry.key }---${ entry.value }<br/>
</c:forEach>
<hr/>
<!-- 2.遍历List集合---list中存放 Student类,有属性:编号,用户名,密码,年龄,电话信息 -->
<%
List<Student> stus = new ArrayList<Student>();
for (int i = 0; i < 10; i++) {
// int id, String name, String password, int age, String phone
stus.add(new Student(i,"name"+i,"pass"+i,i+18,"phone"+i));
}
request.setAttribute("stus", stus);
%>
<table>
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
<th>年龄</th>
<th>电话</th>
<th>操作</th>
</tr>
<%--
items 是设置遍历的数据源
var 是设置当前正在遍历到的数据
begin 属性设置遍历开始的索引
end 属性设置结束的索引
step 属性设置遍历的步长值
varStatus 属性是当前正在遍历的数据的状态
--%>
<c:forEach begin="2" end="8" items="${ stus }" step="2" var="stu" varStatus="status">
<c:choose>
<c:when test="${ status.count == 3 }">
<tr bgcolor="yellow">
</c:when>
<c:otherwise>
<tr>
</c:otherwise>
</c:choose>
<td>${ stu.id }</td>
<td>${ stu.name }</td>
<td>${ stu.password }</td>
<td>${ stu.age }</td>
<td>${ stu.phone }</td>
<td>${ status.index },${ status.count },${ status.first },${ status.last },${ status.begin },${ status.end },${ status.step }</td>
</tr>
</c:forEach>
</table>
</body>
varStatus属性的介绍:
