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属性的介绍: