使用JSTL,可以像EL表达式那样不用编写Java代码就能开发出复杂的JSP页面。JSTL一般要结合EL表达式一起使用。
使用JSTL标签库之前,就必须在Wed项目的lib目录中加入两个jar包:jstl.jar和standard.jar,然后再在需要使用JSTL的JSP页面,加入支持JSTL的taglib指令,如下:
<%@ taglib uri="http://java.sun.com.jsp/jstl/core" prefix="c" %>
其中,prefix="c"表示在当前页面中,JSTL标签库是通过标签<c: >使用的。
1.JSTL核心标签库
JSTL核心标签库主要包含三类:通用标签库、条件标签库和迭代标签库。
(1)通用标签库包含三个标签:赋值标签<c: set>、输出标签<c: out>、移除标签<c: remove>
赋值标签<c: set>的作用是给变量在某个作用域内赋值,有两个版本:“var”版 和 “target”版。
“var”版 , 用于给page、request、session或application作用域内的变量赋值。其语法如下:
<c:set var="elementVar" value="elementValue" scope="scope" />
var :需要赋值的变量名
value:被赋值的变量值
scope:此变量的作用域,有四个可选项,即page、request、session和application,其实例如下:
<c: set var="addError" value="error" scope="request"/>
表示在request作用域内,设置一个addError变量,并将变量值赋值为error,等价于 request.setAttribute("addError","error")
"target"版 : 用于给JavaBean对象的属性或Map对象赋值
a.给JavaBean对象的属性赋值,其语法如下:
<c: set target="objectName" property="propertyName" value="propertyValue" scope="scope">
target:需要操作的JavaBean对象,通常使用EL表达式来表示
property:对象的属性名
value:对象的属性值
scope:此属性值的作用域,有四个可选项,即page、request、session和application。
其实例如下:
package entity;
public class Address {
private String homeAddress;
private String schoolAddress;
public String getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(String homeAddress) {
this.homeAddress = homeAddress;
}
public String getSchoolAddress() {
return schoolAddress;
}
public void setSchoolAddress(String schoolAddress) {
this.schoolAddress = schoolAddress;
}
}
---------------------------------------------
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Address address = new Address();
address.setSchoolAddress("北京天安门");
request.setAttribute("address", address);
request.getRequestDispatcher("jsp/stu.jsp").forward(request, response);
}
-----------------------------------------------
<body>
使用JSTL赋值之前:${address.schoolAddress} <br/>
<c:set target="${requestScope.address }" property="schoolAddress" value="美国洛杉矶"/>
使用JSTL赋值后:${address.schoolAddress }
</body>
b.给Map对象赋值,其语法如下:
<c:set target="mapName" property="mapKey" value="mapValue" scope="scope"/>
target:需要操作的Map对象,通常使用EL表达式来表示。
property:表示Map对象的key
value:表示对象的value
scope:此Map对象的作用域,有四个可选项,即page、request、session和application
其实例如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String,String> map = new HashMap<String,String>();
map.put("dog", "小狗");
request.setAttribute("map", map);
request.getRequestDispatcher("jsp/stu.jsp").forward(request, response);
}
---------------------------------------
<body>
使用JSTL赋值之前:${map.dog} <br/>
<c:set target="${map}" property="dog" value="哈士奇"/>
使用JSTL赋值后:${map.dog}
</body>
需要注意的是,<c:set>标签不仅能对已有变量赋值;如果需要赋值的变量并不存在,<c:set>也会自动产生改对象,如下:
<body>
在request作用域内,并不存在temp变量:${requestScope.temp }<br/>
使用c:set直接给temp赋值为littleGirl<br/>
<c:set var="temp" value="秋田" scope="request"/>
再次观察temp变量: ${requestScope.temp }
</body>
(2)条件标签库
JSTL的条件标签库,包含单重选择标签<c:if>和多重选择标签<c:choose>、<c:when>、<c:otherwise>。
(1)单重选择标签<c:if>
类似于Java中的if选择语句,其语法如下:
<c:if test="condition" var="variableName" scope="scope">
代码块
</c:if>
test:判断条件,值为true或false,通常用EL表达式表示。当值为true时才会执行代码块中的内容。
var:可选项,保存test的判断结果(true或false)
scope:可选项。设置此变量的作用域,有四个可选项:page、request、session、application。
其实例如下:
<body>
<c:if test="${3>2 }" var="result" scope="request">
3>2的结果是:${result }
</c:if>
</body>
(2)多重选择标签<c:choose>
功能类似于Java中的多重if,其语法如下:
<c:choose>
<c:when test="">
代码块1
</c:when>
<c:when test="">
代码块2
</c:when>
...
<c:otherwise>
代码块n
</c:otherwise>
</c:choose>
其中,<c:when test="">类似于Java中的判断句:if()和else if();<c:otherwise>类似于多重if中最后的else。具体流程是:当<c:when>中的test为true时,执行当前<c:when>标签中的代码块;如果所有when中的test都为fasle,则会执行<c:otherwise>中的代码块。其实例如下:
<body>
<c:set var="role" value="学生"/>
<c:choose>
<c:when test="${role eq '老师' }"> <!--eq是等于的意思 -->
老师相关代码
</c:when>
<c:when test="${role eq '学生' }">
学生相关代码
</c:when>
<c:otherwise>
管理员相关代码
</c:otherwise>
</c:choose>
</body>
3.迭代<c:forEach>标签库
在Java中有两种for循环,一种是传统的for循环,形式如:for(int i=0;i<10;i++),另一种是增强的for循环,形式如:for(String name :names),其中names是字符串数组。类似的,在JSTL中也提供了两种<c:forEach>标签与之相对应,一种用于遍历集合对象的成员,另一种用于让代码重复地循环执行。
(1)遍历集合对象的成员
其语法如下:
<c:forEach var="variableName" items="collectionName" varStatus="variableStatusInfo" begin="beginIndex" end="endIndex"
step="step">
迭代集合对象的相关代码
</c:forEach>
var:当前对象的引用,即表示循环正在遍历的那个对象。例如,当循环遍历到第一个成员时,var就代表第一个成员;当循环遍历到第二个成员时,var就代表第二个成员.....
items:当前循环的集合名
varStatus:可选项,存放var所引用成员的相关信息,如索引号(index)等
begin:可选项,遍历集合的开始位置,从0开始
end:可选项,遍历集合的结束位置。
step:可选项,默认为1。遍历集合的步长,比如当step为1时,会依次遍历第0个、第1个、第2个......;当step为2时,会依次遍历第0个,第2个,第4个.....
其实例如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Address addr1 = new Address();
Address addr2 = new Address();
addr1.setSchoolAddress("广西大学");
addr1.setHomeAddress("柳州北区");
addr2.setSchoolAddress("湖南大学");
addr2.setHomeAddress("南宁青秀区");
List<Address> list = new ArrayList<Address>();
list.add(addr1);
list.add(addr2);
request.setAttribute("list",list);
request.getRequestDispatcher("jsp/stu.jsp").forward(request, response);
}
<body>
<c:forEach items="${list }" var="addr" varStatus="sta">
${sta.index }:
家庭地址:${addr.homeAddress }---
学校地址:${addr.schoolAddress }<br/>
</c:forEach>
</body>
(2)迭代指定的次数,其语法如下:
<c:forEach var="variableName" varStatus="variableStatusInfo" begin="biginIndex" end="endIndex" step="step">
循环体
</c:forEach>
其中,var、varStatus、begin、end、step属性的含义,与“遍历集合对象的成员”中对应的属性含义相同,并且能发现此种方式的
<c:forEach>缺少了items属性。此种方式的<c:forEach>主要用来让循环体执行固定的次数。其实例如下:
<body>
<c:forEach begin="0" end="3" step="1" varStatus="status">
${status.index }:萨摩耶<br/>
</c:forEach>
</body>