EL表达式和JSTL标签库
之前我们讲到纯JSP页面的代码可读性太差了,而且写的人也不太爽,今天就来介绍两个新的技术来让写的人爽一点,读的人也爽一点。
这两个技术就是EL表达式和JSTL标签。
先来介绍一下EL表达式:
EL表达式简单来说就是向页面中用一种简单的方式输出值,格式是${表达式}
EL表达式输出的格式是: ${表达式} 表达式若是null,输出空串,jsp表达式脚本输出null值的时候输出null字符串
示例:
<% request.setAttribute("key","值"); %> 表达式脚本输出:<%=request.getAttribute("key")==null?"":request.getAttribute("key")%> <br/> EL表达式输出key的值是:${key}
页面输出:
通过EL表达式也可以获取bean对象或者是数组集合中的元素:
实例:
bean对象:
public class Person { private String name; private String[] phones; private List<String> cities; private Map<String,Object> map; } //所有属性均实现get,set方法,并且实现toString()方法
EL表达式:
<% bean.Person person = new Person(); person.setName("cby"); person.setPhones(new String[]{"123","1234","12345"}); List<String> cites = new ArrayList<>(); cites.add("北京"); cites.add("上海"); cites.add("深圳"); person.setCities(cites); Map<String,Object> map = new HashMap<>(); map.put("key1","value1"); map.put("key2","value2"); map.put("key3","value3"); person.setMap(map); pageContext.setAttribute("p",person); %> 输出person: ${p}<br/> 输出person的name属性: ${p.name} <br/> 输出person的phones数组属性: ${p.phones[0]} <br/>
输出person的Cities集合中的元素: ${p.cities} <br/>
输出person的map集合: ${p.map.get("key1")} <br/>
页面输出:
注意这里我们直接用 . 运算符来获取对象中的元素,但是bean对象中这些属性都是封装好的,我们为什么还能获取呢?
那是因为EL表达式获取这里的属性不是真的用 . 运算符来获取,而是调用对应的get方法获取的,所以我们在定义bean的时候一定要注意实现get set方法
EL表达式如果表达式的值为真的话输出true,如果为假输出false
实例:
${12 == 12}<br/> ${!true}<br/>
页面输出:
EL表达式还自带了一种运算符 : empty
empty运算,可以判断一个数据是否为空,如果是空,则输出true,不为空输出false 以下几种情况为空: 1.值为null 2.值为空串 3.值是Object数组长度为0 4.List集合元素个数为0 5.map集合,元素个数为0
示例:
<% Object[] a = new List[0]; request.setAttribute("emptyNull",null); request.setAttribute("emptyList",a); %> ${empty emptyNull}<br/> ${empty ""}<br/> ${empty emptyList}<br/>
输出:
EL表达式的 . 运算和 [] 运算:
点运算和中括号运算 点运算可以输出bean对象中某个属性的值 中括号运算可以输出有序集合中某个元素的值 还可以输出map集合中key中含有特殊字符的key的值
示例:
<% Map<String,Object> map =new HashMap<String,Object>(); map.put("a.a.a","aaaValue"); map.put("b+b+b","bbbValue"); map.put("c-c-c","cccValue"); request.setAttribute("map",map); %> ${map["a.a.a"]}<br/> ${map["b+b+b"]}<br/> ${map["c-c-c"]}<br/>
输出:
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> 可以获取请求参数的值 paramValue Map<String,String[]> 获取请求参数的值,获取多个值的时候使用 header Map<String,String> 获取请求头的信息 headerValues Map<String,String[]> 获取请求头的信息,多个值得情况 cookie Map<String,Cookie> 可以获取当前请求的Cookie信息 initParam Map<String,String> 可以后驱web.xml中配置的<context-param>上下文参数
其中EL获取4个特定域的属性:
pageScope ==== pageContext域 requestScope ==== Request域 sessionScope ==== Session域 applicationScope ==== ServletContext域
示例:
<% pageContext.setAttribute("key1","pageContext1"); pageContext.setAttribute("key2","pageContext2"); request.setAttribute("key1","requestContext1"); session.setAttribute("key1","sessionContext1"); application.setAttribute("key1","applicationContext1"); %>
${pageScope.key2}<br/> ${requestScope.key1}<br/> ${sessionScope.key1}<br/> ${applicationScope.key1}<br/>
页面输出:
pageContext中的request的其他方法:
request.getScheme() 协议 request.getServerName() 服务器ip request.getServerPort() 服务器端口 request.getContextPath() 获取工程路径 request.getMethod() 获取请求方法 request.getRemoteHost() 获取客户端ip地址 session.getId() 获取会话的id编号
示例:
1.协议:${pageContext.request.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/>
输出:
获取请求参数:
param只能获取一个值 paramValues可以获取多个值 请求地址:http://localhost:8080/demo/EL_JSTL/d.jsp?username=cby&password=123&&username=cby123
示例:
输出请求参数username的值:${param.username}<br/> 输出请求参数username的值:${paramValues.username[1]}<br/>
页面输出:
其他示例:
获取请求头User-agent的信息:${header["User-agent"]}<br/> 获取请求头Connection的信息:${header["Connection"]}<br/> 获取请求头User-agent的信息:${headerValues["User-agent"][0]}<br/>
页面输出:
示例:
先在web.xml中配置:
<context-param> <param-name>username</param-name> <param-value>context</param-value> </context-param>
EL表达式:
输出<Context-param>的值${initParam.username}
页面输出:
JSTL标签库:我们如果想使用的话首先要下载jar包,还要在jsp页面顶部配置这样一行代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL的标签:
i.
i.<c:set /> 作用:set标签可以往域中保存数据 域对象.setAttribute(key,value) scope 设置保存到哪个域 page表示pageContext域(默认值) request表示request域 session表示session域 application表示application域 var属性设置键 value属性设置值
示例:
保存之前:${requestScope.abc}<br/> <c:set scope="request" var="abc" value="123"/> 保存之后:${requestScope.abc}<br/>
页面输出:
ii.
ii. <c:if test="EL判断表达式"></c:if>用来做if判断
示例:
<c:if test="${12==12}"> <h1>12等于12</h1><br/> </c:if>
页面输出:
iii.
iii. <c:choose> <c:when> <c:otherwise> 标签 作用:多路判断 跟switch ... case ... default非常接近 choose标签开始选择判断, when标签表示每一种判断情况 test属性表示当前判断的情况的值 otherwise标签表示剩下的情况 <c:choose> <c:when> <c:otherwise> 标签 1. 标签里不能使用html注释 (报错) 要使用jsp注释 2. when标签的父标签一定要是choose标签
示例:
<% request.setAttribute("height",198); %> <c:choose> <c:when test="${requestScope.height > 190}"> <h2>小巨人</h2> </c:when> <c:when test="${requestScope.height > 180}"> <h2>很高</h2> </c:when> <c:when test="${requestScope.height > 170}"> <h2>还可以</h2> </c:when> <c:otherwise> <h2>剩下的</h2> </c:otherwise> </c:choose>
页面输出:
iiii.
<c:forEach begin="开始的索引" end="结束的索引"> </c:forEach> 作用:遍历输出使用 var属性表示循环的变量 (也是当前正在遍历到的数据)
示例:
<c:forEach begin="1" end="10" var="i"> ${i} </c:forEach> <br/>
输出:
遍历Object数组 for(Object : arr) items表示遍历的数据源(遍历的集合) var表示当前遍历到的数据
示例:
<% request.setAttribute("arr",new String[]{"123","1234","12345","123456"}); %> <c:forEach items="${requestScope.arr}" var="item"> ${ item }<br/> </c:forEach>
页面输出:
示例:
<% Map<String,Object> map = new HashMap<String,Object>(); map.put("key1","value1"); map.put("key2","value2"); map.put("key3","value3"); request.setAttribute("map",map); //for(Map.Entry<String,Object> entry : map.entrySet) { //} %> <c:forEach items="${requestScope.map}" var="entry"> ${ entry.key } = ${ entry.value }<br/> </c:forEach>
页面输出:
综合运用:
<% List<Student> stuList = new ArrayList<Student>(); for(int i=0;i<10;i++){ int t = i+1; stuList.add(new Student(t,"name"+t,(int)(Math.random()*5-3)+18,"1769693636"+i)); } request.setAttribute("stus",stuList); %> <table style="border: 1px solid red"> <tr> <th>学号</th> <th>姓名</th> <th>年龄</th> <th>电话</th> </tr> <c:forEach begin="3" end="5" varStatus="status" items="${requestScope.stus}" var="stu"> <tr> <td>${stu.id}</td> <td>${stu.name}</td> <td>${stu.age}</td> <td>${stu.phone}</td> </tr> </c:forEach> </table>
页面输出:
JSTL循环标签中属性及其意义:
items 遍历的集合 var 遍历到的数据 begin 遍历的开始索引值 end 结束的索引值 step 遍历的步长值 varStatus 当前遍历到的数据的状态
LoopTagStatus源码中有这么几个方法(status调用): Object getCurrent() 表示获取当前遍历到的数据 int getIndex() 表示获取遍历的索引 int getCount() 表示遍历的个数 boolean isFirst() 表示是否当前遍历的数据是否是第一条 boolean isLast() 表示是否当前遍历的数据是否是最后一条 Integer getBegin() \ Integer getEnd() - 获取begin,end,step的属性值 Integer getStep() /