從 JSTL 中的 forEach 迴圈取得索引值
1. 概述
使用 JavaServer Pages (JSP) 時,我們經常使用 JavaServer Pages 標準標記庫 (JSTL) 來簡化程式碼。
最常用的 JSTL 標籤之一是<c:forEach>
,它允許我們迭代數組、列表或映射等集合。在迭代時,我們經常需要存取每個元素的索引。
在本快速教學中,我們將探索在使用 JSTL <c:forEach>
標籤進行迭代時取得元素的索引值。
2. 建立一個簡單的範例
作為範例,我們將創建一個簡單的 Spring-MVC JSTL Web 應用程式來列出一些預先定義的影片。為了簡單起見,我們將跳過 Spring ViewResolver
等 Spring 設定。
首先我們來看看Movie
POJO:
public class Movie {
private String title;
private int year;
public Movie(String title, int year) {
this.title = title;
this.year = year;
}
//... getter and setter methods are omitted
}
然後,我們需要一個 Spring Controller
類別來處理 HTTP 請求。因此,讓我們創建一個:
@Controller
public class JSTLForEachDemoController {
@RequestMapping(value = "/foreach-demo", method = RequestMethod.GET)
public ModelAndView forEachDemo(final Model model) {
ModelAndView mv = new ModelAndView("jstlForEachDemo");
List<Movie> movies = List.of(
new Movie("The Hurt Locker", 2008),
new Movie("A Beautiful Mind", 2001),
new Movie("The Silence of the Lambs", 1991),
new Movie("A Man for All Seasons", 1966),
new Movie("No Country for Old Men", 2007)
);
mv.addObject("movieList", movies);
return mv;
}
}
我們可以看到, JSTLForEachDemoController
類別只有一個方法來處理「 /foreach-demo
」 GET 請求。為了簡單起見,我們準備了一個硬編碼的Movie
物件List
,並將其新增至名為「 movieList
」 的ModelAndView
物件中。另外,我們定義了jstlForEachDemo
作為呈現Movie
資料的視圖。
最後,讓我們在webapp/WEB-INF/views/jstlForEachDemo.jsp
建立一個 JSP 檔案作為視圖:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
<head>
<title>JSTL ForEach Example</title>
</head>
<body>
<h1>Movie List</h1>
<div>
<table style="width: 50%">
<tr>
<th>Year</th>
<th>Title</th>
</tr>
<c:forEach var="movie" items="${movieList}">
<tr>
<td>${movie.year}</td>
<td>${movie.title}</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
如程式碼範例所示,我們使用 JSTL 的<c:forEach>
標籤循環遍歷movieList
物件並產生 HTML 表中的行。
如果我們將 Web 應用程式部署到 servlet 容器(例如 Apache Tomcat),我們可以透過在 Web 瀏覽器中存取 URL 來查看影片的資料:
接下來,讓我們弄清楚如何在forEach
迭代期間取得每個Movie
元素的索引。
3. 使用varStatus
存取索引和計數
幸運的是,JSTL 提供了一種內建機制,用於在forEach
循環中取得元素的索引。 varStatus
屬性允許我們定義一個循環狀態變量,提供有關迭代的有用元資料。
接下來,讓我們將varStatus
屬性新增至<c:forEach>
標籤並在 HTML 表中顯示元素索引:
...
<h1>Movie List</h1>
<div>
<table style="width: 50%">
<tr>
<th>varStatus.index</th>
<th>Year</th>
<th>Title</th>
</tr>
<c:forEach var="movie" items="${movieList}" varStatus="theLoop">
<tr>
<td>${theLoop.index}</td>
<td>${movie.year}</td>
<td>${movie.title}</td>
</tr>
</c:forEach>
</table>
</div>
...
在這個例子中,我們在forEach
循環中將varStatus
命名為“theLoop”
,並透過存取varStatus
的index
屬性來取得元素的索引: theLoop.index
。
現在,如果我們訪問相同的 URL,我們可以看到包含movieList:
如截圖所示, varStatus
的index
從零開始。然而,有時,我們希望在我們的視圖中有基於一的索引。當然,我們可以透過在varStatus
的index
上加一來快速實現,例如${theLoop.index + 1}.
事實上, varStatus
提供了count
屬性,它提供了基於一的索引。
接下來,讓我們使用varStatus.count
在基於零的索引列旁邊新增另一個基於一的索引列:
...
<h1>Movie List</h1>
<div>
<table style="width: 50%">
<tr>
<th>varStatus.index</th>
<th>varStatus.count</th>
<th>Year</th>
<th>Title</th>
</tr>
<c:forEach var="movie" items="${movieList}" varStatus="theLoop">
<tr>
<td>${theLoop.index}</td>
<td>${theLoop.count}</td>
<td>${movie.year}</td>
<td>${movie.title}</td>
</tr>
</c:forEach>
</table>
</div>
...
讓我們重新部署我們的應用程式並在瀏覽器中檢查結果:
如預期的那樣,該表包含基於一的索引。
4. varStatus
的其他有用屬性
使用 JSTL 的<c:forEach>
標籤中的內建varStatus
屬性,我們成功取得了元素索引。除了index
和count
之外, varStatus
還提供其他有價值的屬性。
有時,在循環中,我們需要偵測當前元素是第一個還是最後一個。例如,我們想為 HTML 表中的第一部和最後movie
設定不同的背景顏色。
varStatus
提供兩個布林屬性, first
和last
,它們分別允許我們輕鬆偵測我們是否處於第一次迭代或最後一次迭代。
接下來,讓我們透過檢查varStatu
的first
和last
屬性來為影片的第一行和最後一行設定不同的背景顏色:
...
<style>
...
.first { background-color: lightgreen }
.last { background-color: orange }
</style>
...
<h1>Movie List</h1>
<div>
<table style="width: 50%">
<tr>
<th>varStatus.index</th>
<th>varStatus.count</th>
<th>Year</th>
<th>Title</th>
</tr>
<c:forEach var="movie" items="${movieList}" varStatus="theLoop">
<tr ${ theLoop.first ? 'class="first"' : '' } ${ theLoop.last ? 'class="last"' : '' }>
<td>${theLoop.index}</td>
<td>${theLoop.count}</td>
<td>${movie.year}</td>
<td>${movie.title}</td>
</tr>
</c:forEach>
</table>
</div>
...
我們為背景顏色定義了兩個 CSS 類別。然後,在<tr>
標籤中,
我們透過檢查varStatus
的first
和last
屬性來設定對應的類別名稱。
修改完成後,我們在瀏覽器中看看結果:
現在,第一行的背景是淺綠色,最後一行的背景是橘色。
5. 結論
在本文中,我們探討如何使用 JSTL 在 JSP 中的<c:forEach>
循環內存取索引。無論我們是需要基於零的索引來實現邏輯,還是需要基於一的計數來實現顯示目的,JSTL 都提供了一種易於使用的解決方案來有效地處理循環。
此外,我們也示範如何使用varStatus
的first
和last
屬性來偵測<c:forEach>
迴圈中的第一次和最後一次迭代。
與往常一樣,範例的完整原始程式碼可 在 GitHub 上找到。