JSTL:JSP Standard Tag Library 标准标签库
JSTL 允许开发人员可以像使用 HTML 标签那样在 JSP 中开发 Java 功能。
JSTL 库有:
- core
- i18n
- fmt
- sql
- ......
i18n 和 sql 用的很少,core 和 fmt 在工作中会使用,本文主要介绍 core 和 fmt。
1. 导入 jar 包
为了能够在 JSP 中使用 JSTL,首先需要两个 jar 包,分别是 jstl.jar 和 standard.jar,把这两个 jar 包放在 web/WEB-INF/lib 下
2. set out remove
在页面中使用 JSTL 需要在 jsp 中通过指令进行设置。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
//prefix="c" 表示后续的标签使用都会以 <c: 开头
<c:set var="name" value="${'gareen'}" scope="request"/>
//在作用域 request 中设置 name,相当于 <%request.setAttribute("name","gareen")%>
<c:out value="${name}"/>
//相当于 <%=request.setAttribute("name")%>
<c:remove var="name" scope="request"/>
//在作用域request中删掉name,相当于 <%request.removeAttribute("name")%>
作用域可以是pageContext,request,session,application。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="name" value="${'gareen'}" scope="request" />
通过标签获取name: <c:out value="${name}" /> <br>
<c:remove var="name" scope="request" /> <br>
通过标签获取name: <c:out value="${name}" /> <br>
3. if else
JSTL 通过 <c:if test=""> 进行条件判断
但是 JSTL 没有 <c:else,所以常使用的办法是在 <c:if 的条件里取反。
配合 if 使用的还有通过 empty 进行空判断,empty 可以判断对象是否为 null,字符串长度是否为 0,集合长度是否为 0。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="hp" value="${10}" scope="request" />
<c:if test="${hp<5}">
<p>这个英雄要挂了</p>
</c:if>
<c:if test="${!(hp<5)}">
<p>这个英雄觉得自己还可以再抢救抢救</p>
</c:if>
<%
pageContext.setAttribute("weapon", null);
pageContext.setAttribute("lastwords", "");
pageContext.setAttribute("items", new ArrayList());
%>
<c:if test="${empty weapon}">
<p>没有装备武器</p>
</c:if>
<c:if test="${empty lastwords}">
<p>挂了也没有遗言</p>
</c:if>
<c:if test="${empty items}">
<p>物品栏为空</p>
</c:if>
4. choose
虽然 JSTL 没有提供 else 标签,但是提供了一个 else 功能的标签。
<c:choose>
<c:when test="${hp<5}">
</c:when>
<c:otherwise>
</c:otherwise>
</c:choose>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="hp" value="${3}" scope="request" />
<c:choose>
<c:when test="${hp<5}">
<p>这个英雄要挂了</p>
</c:when>
<c:otherwise>
<p>这个英雄觉得自己还可以再抢救抢救</p>
</c:otherwise>
</c:choose>
5. forEach
可以在 JSP 中使用 for 循环,但是其可读性很差。借助 JSTL 的 c:forEach 标签,可以改善可读性。
<c:forEach items="${heros}" var="hero" varStatus="st">
items="${heros}" 表示遍历的集合
var="hero" 表示把每一个集合的元素放在 hero 上
varStatus="st" 表示遍历的状态
6. forTokens
<c:forTokens 专门用于字符串拆分,并且可以指定多个分隔符
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="heros" value="塔姆,艾克;巴德|雷克赛!卡莉丝塔" />
<c:forTokens items="${heros}" delims=":;|!" var="hero">
<c:out value="${hero}" /> <br />
</c:forTokens>
7. fmt:formatNumber 格式化数字
fmt 标签常用来进行格式化,其中 fmt:formatNumber 用于格式化数字,使用之前要加上
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>
<fmt:formatNumber 表示格式化数字
minFractionDigits 小数点至少要有的位数
maxFractionDigits 小数点最多能有的位数
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<c:set var="money" value="888.8" />
<c:set var="pi" value="3.1415926" />
最少两个小数点:
<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>
<br>
最多两个小数点:
<fmt:formatNumber type="number" value="${pi}" maxFractionDigits="2" />
8. fmt:formatDate 格式化日期
fmt 标签常用来进行格式化,其中 fmt:formatDate 用于格式化日期,和 fmt:formatNumber 用于格式化数字一样,使用之前要加上:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/>
<fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate 表示格式化日期
yyyy 表示年份
MM 表示月份
dd 表示日期
E 表示星期几
a 表示是上午还是下午
HH 表示小时
mm 表示分钟
ss 表示秒
S 表示毫秒
z 表示时区
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<%
Date now = new Date();
pageContext.setAttribute("now",now);
%>
完整日期: <fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/><br>
完整时间: <fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/><br>
常见格式: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>
9. fn:
fn标签提供各种实用功能,首先使用之前使用加入如下指令:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
用法举例:
${fn:substring(name, 0, 5)}
//获取name的前5位
函数 | 描述 |
fn:contains(string, substring) | 如果参数string中包含参数substring,返回true |
fn:containsIgnoreCase(string, substring) | 如果参数string中包含参数substring(忽略大小写),返回true |
fn:endsWith(string, suffix) | 如果参数 string 以参数suffix结尾,返回true |
fn:escapeXml(string) | 将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回 |
fn:indexOf(string, substring) | 返回参数substring在参数string中第一次出现的位置 |
fn:join(array, separator) | 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。 |
fn:length(item) | 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。 |
fn:replace(string, before, after) | 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果 |
fn:split(string, separator) | 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素 |
fn:startsWith(string, prefix) | 如果参数string以参数prefix开头,返回true |
fn:substring(string, begin, end) | 返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符 |
fn:substringAfter(string, substring) | 返回参数substring在参数string中后面的那一部分字符串 |
fn:substringBefore(string, substring) | 返回参数substring在参数string中前面的那一部分字符串 |
fn:toLowerCase(string) | 将参数string所有的字符变为小写,并将其返回 |
fn:toUpperCase(string) | 将参数string所有的字符变为大写,并将其返回 |
fn:trim(string) | 去除参数string 首尾的空格,并将其返回 |
EL 表达式语言
EL(Expression Language) 是为了使 JS P写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让 JSP 的代码更加简化。
1. 取值
不同版本的 tomcat 是否默认开启对 EL 表达式的支持,是不一定的。
所以为了保证 EL 表达式能够正常使用,需要在 <%@page 标签里加上:
isELIgnored="false"
使用 EL 表达式非常简单,比如使用 JSTL输出要写成:
<c:out value="${name}" />
但是用 EL 只需要:
${name}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="name" value="${'gareen'}" scope="request" />
通过标签获取name: <c:out value="${name}" /> <br>
通过 EL 获取name: ${name}
2. 作用域优先级
EL 表达式可以从 pageContext,request,session,application 四个作用域中取到值,如果4个作用域都有 name 属性怎么办?
EL 会按照从高到低的优先级顺序获取
pageContext > request > session > application
3. JavaBean 概念
EL 可以很方便的访问 JavaBean 的属性,那么 JavaBean 是什么呢?
JavaBean 的标准:
- 1. 提供无参 public 的构造方法(默认提供)
- 2. 每个属性,都有 public 的 getter 和 setter
- 3. 如果属性是 boolean,那么就对应 is 和 setter 方法
比如示例代码中的 Hero 类,默认提供了一个无参的 public 的构造方法。 同时每个属性都有 getter 和 setter。
package bean;
public class Hero {
public int id;
public String name;
public float hp;
public int damage;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getHp() {
return hp;
}
public void setHp(float hp) {
this.hp = hp;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
}
4. 获取 JavaBean 的属性
获取 JavaBean 的属性,只需要通过 . 符号操作就可以了。像这样 ${hero.name} ,就会自动调用 getName 方法了。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" import="bean.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
Hero hero =new Hero();
hero.setName("盖伦");
hero.setHp(616);
request.setAttribute("hero", hero);
%>
英雄名字 : ${hero.name} <br>
英雄血量 : ${hero.hp}
5. 结合 JSTL 的 <c:forEach
原代码中:
<c:out value="${hero}" />
可以写为:
${hero}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
List<String> heros = new ArrayList<String>();
heros.add("塔姆");
heros.add("艾克");
heros.add("巴德");
heros.add("雷克赛");
heros.add("卡莉丝塔");
request.setAttribute("heros",heros);
%>
<table width="200px" align="center" border="1" cellspacing="0">
<tr>
<td>编号</td>
<td>英雄</td>
</tr>
<c:forEach items="${heros}" var="hero" varStatus="st" >
<tr>
<td>${st.count}</td>
<td>${hero}</td>
</tr>
</c:forEach>
</table>
6. 取参
EL 表达式还可以做到 request.getParameter("name") 这样的形式获取浏览器传递过来的参数。
先把 jstl.jsp 代码改为如例所示,然后访问如下地址:
http://127.0.0.1/jstl.jsp?name=abc
可以观察到获取了参数 name
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*" isELIgnored="false"%>
${param.name}
7. eq
进行条件判断,大大简化了 JSTL 的 c:if 和 c:choose 代码
如例,一行代码就能起到其他好几行代码的效果
${killNumber ge 10? "超神":"还没超神" }
例子中讲的是大于等于,除此之外的其他用法如下:
eq 相等 ne、neq 不相等,
gt 大于, lt小于
gte、ge 大于等于
lte、le 小于等于
not 非 mod 求模
is [not] div by 是否能被某数整除
is [not] even 是否为偶数
is [not] odd 是否为奇