EL
1.提出问题,为什么要使用EL
在JSP页面上,有两类操作非常常用,从对象域中读取属性,获取请求参数。目前使用JSP脚本片段和JSP表达式代码很繁琐,不易于维护。需要更加简洁的语法格式。
2.EL Expression Language
主要功能:
①获取请求参数并显示,当前请求参数没有获取到时显示空字符串即,而不是null
②读取4个域对象属性值
pageContext request session application
3.EL表达式的语法格式
${表达式内容 }
EL表达式在JSP页面上可以直接使用
4.EL表达式中可以直接使用的隐含对象
①第一组:JSP隐含对象
pageContext : ${pageContext }通过pageContext可以获取其他8个隐含对象
②第二组:域对象对应的Map
pageScope : ${pageScope }相当于pageContext.getAttribute(属性名)
requestScope : ${requestScope }
sessionScope : ${sessionScope }
applicationScope : ${applicationScope }
③第三组:对应请求参数对应的Map
param : ${param }对应一个单独的请求参数值
paramValues : ${paramValues }对应一组单独的请求参数值
5.EL表达式获取值的方法
①使用”点”获取
<1>调用的对象是Map,根据key获取
${requestScope.attrName }相当于requestMap.get(attrName)
<2>调用的对象是一个普通的Java对象,根据属性名获取
★属性名的定义方式:属性名和getXxx()方法setXxx()方法的对应关系是:get或set+属性名首字母大写
例如:有字段为employeeName,有get、set方法为
则属性名为empName,与字段名无关
<%
Employee employee = new Employee("Good");
request.setAttribute("emp", employee);
%>
${requestScope.emp }<br />
${requestScope.emp.empName }会调用Employee对象的getEmpName()方法
②使用“[]”获取
因为某些情况下用来获取值的“键”中含有“.”,为了避免歧义,使用“[]”获取
<p>pageScope:${pageScope.javax.servlet.jsp.jspResponse }</p>
<p>pageScope:${pageScope["javax.servlet.jsp.jspResponse"] }</p>
<%
Employee employee = new Employee("Good");
request.setAttribute("emp", employee);
%>
Employee:${requestScope["emp"] }<br />
EmpName:${requestScope["emp"]["empName"] }
③简化写法
Scope对象可以省略不写,例如${requestScope.emp }可以简写为${emp },此时,系统会根据emp值,在四个域对象中按照从小到大的顺序查找对应的属性,如果找到就不继续找了
如果四个域对象中有属性名重复的属性,那么只能获取到较小范围的那个值,此时只能通过指定具体Scope对象来区别
<%
pageContext.setAttribute("key2", "pageContextValue");
request.setAttribute("key2", "requestValue");
session.setAttribute("key2", "sessionValue");
application.setAttribute("key", "applicationValue");
%>
Attribuite Value----->${key }
6.EL运算
1). 算术运算:${5+3}
2). 关系运算: ${5>3}
3). 逻辑运算: ${true&&false}
4). empty运算:${empty requestScope.emp }
字符串:null和””
Collection集合:null和没有元素的集合
数组:null
Map:null和没有元素的集合
其他情况返回false
5). 三目条件运算: ${16<5?'a':"big" }
7.其他
①获取当前Web应用的路径
传统方式:<%=request.getContextPath() %>
使用EL:${pageContext.request.contextPath }
因为pageContext对象有getRequest()方法,而request对象有getContextPath()方法,所以可以使用属性名直接调用。
JSTL
1.HelloWorld
①导入JAR包
jakarta-taglibs-standard-1.1.2\lib目录下的jstl.jar和standard.jar
②在JSP页面上添加JSP指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
uri属性值指向一个tld文件,这个tld文件是一个标签库声明文件。系统通过uri的值找到tld文件,通过tld文件找到相关的实现类支持JSTL标签的功能。
前缀是在页面上使用JSTL标签的一个别名。
③使用
<%
List<String> list = Arrays.asList("a","b","c");
request.setAttribute("list", list);
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
%>
<a href="#"><%=s %></a>
<%
}
%>
<c:forEach items="${list }" var="item">
<a href="#">${item }</a>--|--
</c:forEach>
2.表达式标签
1). <c:out value="${name}" default="xxx"/>
输出域对象指定属性名所对应的属性值, 如果为null, 显示默认值
<% request.setAttribute("attrName", "attrValue"); %>
Out:<c:out value="${attrName }" default="DefaultValue" />
相当于${attrName },区别是<c:out />能够提供默认值
2.1). <c:set value="${person.name}" var="myName"/>
向域对象中保存指定的属性名和属性值
<c:set value="goodMorning" var="goodName" scope="request" />
通过scope属性指定把属性值存入到哪个域对象中
2.2). <c:set target="${person}" property="name" value="Jack"/>
修改域对象中的javabean属性的属性值
<% Employee emp = new Employee("Justin"); %>
<% request.setAttribute("emp", emp); %>
<c:set target="${emp }" property="empName" value="Philip" />
emp.empName:${emp.empName }<br /><br />
3). <c:remove var="myName"/>
删除域对象中的指定属性
<% Employee emp = new Employee("Justin"); %>
<% request.setAttribute("emp", emp); %>
<c:remove var="emp" scope="request" />
emp.empName:${emp.empName }---<br /><br />
3.分支结构
①c:if标签
<c:if test="判断条件可以是EL表达式">
7真的大于5
</c:if>
<% Employee emp = new Employee("Justin"); %>
<% request.setAttribute("emp", emp); %>
<c:if test="${!empty emp }">
${emp }
</c:if>
②c:choose等
<% Employee emp = new Employee("Justin"); %>
<% request.setAttribute("emp2", emp); %>
<c:choose>没有其他属性,就是为了包含c:when和c:otherwise
<c:when test="${empty emp }">没有设置emp属性</c:when>
<c:when test="${!empty emp }">${emp }</c:when>
通过test属性指定判断条件,可以有多个。在同一个<c:choose>中时,<c:when>必须在<c:otherwise>之前。在同一个<c:choose>下,当有好几个<c:when>都符合条件时,只能有一个<c:when>成立。
<c:otherwise>OtherWise...</c:otherwise>
</c:choose>
4.循环结构
<%
int [] i = new int[]{0,1,2,3,4};
pageContext.setAttribute("arr", i);
%>
<!-- 在forEach标签中,items属性的值是要遍历的集合或数组,var属性是遍历过程中,用来指代某一个元素时的变量 -->
<c:forEach items="${arr }" var="item">
${item }<br />
</c:forEach>
<%
for(int item : i){
out.print(item+"<br />");
}
%>
<%
List<String> list = Arrays.asList("AAA","BBB","CCC","DDD","EEE","FFF","GGG");
pageContext.setAttribute("list", list);
%>
<table>
<tr>
<th>item</th><th>index</th><th>count</th><th>first</th><th>last</th>
</tr>
<c:forEach items="${list }" var="item" begin="1" step="2" varStatus="s">
<tr><td>${item }</td><td>${s.index }</td><td>${s.count }</td><td>${s.first }</td><td>${s.last }</td></tr>
</c:forEach>
</table>
5.URL操作
①我们可以使用c:redirect标签进行重定向,在这个标签中url属性指定要重定向到的地址,这个地址已经包括了当前Web应用的地址,不需要再进一步指定了。
即:url="/target.jsp"相当于/day25_JSTL/target.jsp
url="/path/target.jsp"相当于/day25_JSTL/path/target.jsp
②在c:redirect标签中,可以使用c:param标签进行传递请求参数的操作
<c:redirect url="/path/target.jsp">
<c:param name="paramName" value="paramValue2" />
</c:redirect>