一. JSTL简介
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。那么我们为什么要使用JSTL呢,这里引用火龙果被占用了前辈的回答:
JSP 中最好不要出现 <% %>,因为 JSP 主要是为了显示数据,如果里面掺杂着很多的业务逻辑,将导致不能各司其责,一个 JSP 既要负责数据展现,还要负责数据的逻辑处理,这无论在开发,还是维护上都是让人不可忍受的。
JSTL 一般都是一些控制性质的标签,一般使用 core 的 c 标签,诸如遍历、判断等,至于 JSTL 的其他标签,比如 x, sql 等都是涉及业务逻辑的,在 JSP 中也会导致混乱。记住这一点就行了:JSP 只负责呈现数据,不负责这些数据是从什么地方来的。
二. 使用JSTL
1. 添加依赖
使用JSTL前需要添加standard.jar和jstl.jar依赖,关于依赖的添加方法,可以查看本站《IDEA使用方法》一文
2. 引入标签
引入标签的方式也非常简单,在jsp文件中添加以下指令即可引入JSTL核心库:
<%@ taglib uri="xxxxx" prefix="xxxxx" %>
三. C标签
首先引入c标签:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
prefix可以是任何值,但习惯用c,接下来在Servlet类中创建一个字符串数组,并转发到index.jsp:
package io.zhangjia.servlet; import dao.BikeDao; import dao.impl.BikeDaoImpl; import entity.Bike; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @WebServlet("/zhangjia") public class Servlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String[] names = new String[]{"张三","李四","王五"}; req.setAttribute("names",names); req.getRequestDispatcher("index.jsp").forward(req,resp); } }
1. forEach
forEach和Java中的foreach作用是一样的,foreach有以下几个属性
var:相当于for循环中的for(int i = 1; i <= 10; i+=1)中的int i
begin:相当于for循环中的for(int i = 1; i <= 10; i+=1)中的i = 1
end:相当于for循环中的for(int i = 1; i <= 10; i+=1)中的int <= 10
step:相当于for循环中的for(int i = 1; i <= 10; i+=1)中的i += 1
<c:forEach begin="1" end="10" var="i" step="1"> ${i} </c:forEach> 输出: 1 2 3 4 5 6 7 8 9 10
还可以使用foreach输出数组等对象:
<c:forEach items="${requestScope.names}" var="name"> ${name} </c:forEach> <c:forEach items="${requestScope.books}" var="book"> ${book.id} </c:forEach>
所有代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> <!DOCTYPE html> <html> <head> <title>$Title$</title> </head> <body> <c:forEach begin="1" end="10" var="i" step="1"> ${i} </c:forEach> <c:forEach items="${requestScope.names}" var="name"> ${name} </c:forEach> </body> </html>
2. 判断
判断我们可以直接使用多个if来模拟if-eles
<c:if test="判断"> </c:if>
还可以使用choose来模拟if-else和switch
<c:choose> <c:when test="判断"> </c:when> <c:when test="判断"> </c:when> <c:otherwise> </c:otherwise> </c:choose>
比如根据age大小判断是否成年,根据action内容判断要执行的操作
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %> <!DOCTYPE html> <html> <head> <title>$Title$</title> </head> <body> <c:if test="${param.age >= 18}"> <h1>成年</h1> </c:if> <c:if test="${param.age < 18}"> <h1>未成年</h1> </c:if> <c:choose> <c:when test="${param.age >= 18}"> <h1>成年</h1> </c:when> <c:otherwise> <h1>未成年</h1> </c:otherwise> </c:choose> <c:choose> <%--这里和Java不同,字符串也可以使用==比较--%> <c:when test="${param.action == 'add'}"> <h1>执行添加</h1> </c:when> <c:when test="${param.action == 'update'}"> <h1>执行修改</h1> </c:when> </c:choose> </body> </html>
3. out
out的作用与<%= … >,类似,但是不会渲染html标签
<% pageContext.setAttribute("str","<h1>hello world</h1>"); %> <c:out value="${pageScope.str}"/> <%=pageContext.getAttribute("str")%> ${pageScope.str}
输出如下图:
4. set
set标签可以向作用域内存储数据。<x:set>标签为XPath表达式的值设置一个变量。如果XPath表达式的值是boolean类型,则<x:set>将会设置一个java.lang.Boolean对象,若是字符串,则设置一个java.lang.String对象,若是数字,则设置一个java.lang.Number对象。
我们一般用set来简化contextPath,set常用的几个属性:
var:代表XPath表达式值的变量
value:要保存的信息
scope:变量存储信息范围
<c:set var="path" value="${pageContext.request.contextPath}"/> <c:if test="${sessionScope.user == null}"> <a href="${path}/login.jsp">登录</a> </c:if>
5. remove
<c:remove>标签可以从指定的范围中移除一个变量,相当于pageContext.removeAttribute()
<% pageContext.setAttribute("str","<h1>hello world</h1>"); // pageContext.setAttribute("path",request.getContextPath()); %> <c:out value="${pageScope.str}"/> <c:remove var="str"/> <c:out value="${pageScope.str}"/>
只有第一次out会输出,第二次的out不会输出任何内容,因为已经从pageScope中remove掉。
6. catch
<c:catch>标签捕获其主体中发生的任何Throwable异常,并可选地公开它。
<c:catch var="e"> <% int i = 10 / 0; %> </c:catch> <c:if test="${e != null}"> <p>${e}</p> </c:if>
输出:java.lang.ArithmeticException: / by zero
7. fortoken
之前我们讲过<c:forEach>标签,可以使用它来迭代一组对象,而 <c:forTokens>标签用于将字符串分割成令牌,并遍历每个令牌。
该标签的属性和<c:forEach>基本相同,不同的是多了一个用与设置分隔符的属性:
delims:用作分隔符的字符
<% String imgs = "1.jpg,2.jpg,3.jpg"; pageContext.setAttribute("imgs",imgs); %> <ul> <c:forTokens items="${pageScope.imgs}" delims="," var="img"> <li>${img}</li> </c:forTokens> </ul>
输出:
-
1.jpg
-
2.jpg
-
3.jpg
四. fmt标签
fmt意为格式化标签,和c标签类似,使用fmt标签,也需要先引入:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
1. formatNumber
<fmt:formatNumber>标签用于格式化数字,百分比,货币。常用属性:
-
value:要格式化的数字
-
type:NUMBER(数字),CURRENCY(货币),或 PERCENT(百分比)类型,type不区分大小写
2. formatDate
<fmt:formatDate>标签用于使用不同的方式格式化日期。常用属性:
-
value:要格式化的时间
-
type:DATE(日期), TIME(时间), 或 BOTH(日期+时间)
-
dateStyleFULL, LONG, MEDIUM, SHORT, 或 DEFAULT
-
timeStyleFULL, LONG, MEDIUM, SHORT, 或 DEFAULT
<% Double price = 9.9; Date date = new Date(); pageContext.setAttribute("price",price); pageContext.setAttribute("date",date); %> <p><fmt:formatNumber value="${pageScope.price}" type="CURRENCY"/> </p> <p>${pageScope.date}</p> <p><fmt:formatDate value="${pageScope.date}"/></p> <p><fmt:formatDate value="${pageScope.date}" type="date"/></p> <p><fmt:formatDate value="${pageScope.date}" type="time"/></p> <p><fmt:formatDate value="${pageScope.date}" dateStyle="FULL" timeStyle="full" type="both"/></p> <p><fmt:formatDate value="${pageScope.date}" type="both"/></p> 输出: ¥9.90 Tue Jun 04 17:54:43 GMT+08:00 2019 2019-6-4 2019-6-4 17:54:43 2019年6月4日 星期二 下午05时54分43秒 GMT+08:00 2019-6-4 17:54:43
请登录之后再进行评论