Hôm nay, chúng ta sẽ cùng khám phá một chủ đề cực kỳ quan trọng trong lập trình web Java: JSTL. Nếu bạn đã từng cảm thấy việc viết logic lặp hay điều kiện trực tiếp trong JSP bằng scriptlets (những đoạn mã Java trong <% %>) làm cho mã của bạn trở nên lộn xộn và khó bảo trì, thì JSTL chính là giải pháp mà bạn đang tìm kiếm.

JSTL là gì?
JSTL, viết tắt của JSP Standard Tag Library, là một thư viện thẻ tiêu chuẩn được thiết kế đặc biệt để mở rộng khả năng của JSP. Nó cung cấp các thẻ mạnh mẽ giúp chúng ta kiểm soát hành vi của trang JSP một cách hiệu quả, từ các câu lệnh lặp, điều khiển luồng, cho đến quốc tế hóa và thao tác SQL, v.v.
Trước đây, chúng ta có thể dùng JSP EL (Expression Language) và JSP Action Tags để viết mã JSP giống như HTML, nhưng chức năng của chúng khá hạn chế. Ví dụ, chúng ta không thể lặp qua một collection bằng EL hay các action element, cũng không thể “escape” các thẻ HTML để hiển thị chúng dưới dạng văn bản trên trình duyệt. Đây chính là lúc JSTL phát huy tác dụng vì nó cho phép chúng ta thực hiện nhiều thao tác hơn
JSTL là một phần của Java EE API và thường được bao gồm trong hầu hết các máy chủ servlet. Thay vì nhúng các khối mã Java (scriptlets) trực tiếp vào trang JSP, JSTL cung cấp một bộ các thẻ XML chuẩn, giúp chúng ta thực hiện các tác vụ phổ biến như lặp, điều kiện, xử lý chuỗi, định dạng dữ liệu và tương tác cơ sở dữ liệu.
Cài đặt JSTL
Để sử dụng JSTL trong các trang JSP, bạn cần tải về các file JAR của JSTL và đưa chúng vào thư mục WEB-INF/lib trong ứng dụng web của mình.
Ví dụ, với Tomcat, chúng ta cần bao gồm các file jstl.jar và standard.jar để đưa vào build path của dự án. Nếu chúng không có sẵn trong thư mục lib của máy chủ, bạn nên thêm chúng vào ứng dụng của mình. Nếu bạn sử dụng Maven, hãy thêm các dependency sau vào file pom.xml của mình để tránh lỗi phổ biến như: eclipse Can not find the tag library descriptor for "<https://java.sun.com/jsp/jstl/core>":
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
Các loại JSTL Tags
Dựa trên chức năng, JSTL tags được phân loại thành năm nhóm chính.
- JSTL core tags: JSTL core tags cung cấp hỗ trợ cho các tác vụ lặp, logic điều kiện, xử lý ngoại lệ, tạo URL, chuyển hướng hoặc chuyển tiếp phản hồi, v.v. Để sử dụng JSTL core tags, chúng ta nên đặt nó trong trang JSP như sau:
<%@ taglib uri="<https://java.sun.com/jsp/jstl/core>" prefix="c" %>Trong bài viết này, chúng ta sẽ tập trung vào các JSTL core tags quan trọng.
- JSTL formatting and localisation tags: JSTL formatting tags dùng để định dạng số, ngày tháng và hỗ trợ quốc tế hóa thông qua các locale và resource bundle. Chúng ta có thể bao gồm các thẻ jstl này trong JSP với cú pháp dưới đây:
<%@ taglib uri="<https://java.sun.com/jsp/jstl/fmt>" prefix="fmt" %> - JSTL sql tags: JSTL SQL Tags cung cấp hỗ trợ tương tác với các cơ sở dữ liệu quan hệ như Oracle, MySQL, v.v. Sử dụng JSTL SQL tags, chúng ta có thể chạy các truy vấn cơ sở dữ liệu. Chúng ta sử dụng JSTL tags này trong JSP với cú pháp dưới đây:
<%@ taglib uri="<https://java.sun.com/jsp/jstl/sql>" prefix="sql" %> - JSTL xml tags: JSTL XML tags được sử dụng để làm việc với các tài liệu XML như phân tích cú pháp XML, chuyển đổi dữ liệu XML và đánh giá biểu thức XPath. Cú pháp để bao gồm JSTL XML tags trong trang JSP là:
<%@ taglib uri="<https://java.sun.com/jsp/jstl/xml>" prefix="x" %> - JSTL functions tags: JSTL tags cung cấp một số hàm có sẵn để thực hiện các thao tác phổ biến, hầu hết trong số đó là thao tác chuỗi như nối chuỗi (String Concatenation), tách chuỗi (Split String), v.v. Cú pháp để bao gồm các hàm JSTL trong trang JSP là:
<%@ taglib uri="<https://java.sun.com/jsp/jstl/functions>" prefix="fn" %>
Lưu ý rằng tất cả các URI của JSTL standard tags đều bắt đầu bằng https://java.sun.com/jsp/jstl/ và chúng ta có thể sử dụng bất kỳ tiền tố (prefix) nào chúng ta muốn, nhưng tốt nhất là nên dùng các tiền tố mặc định như ‘c’, ‘fmt’, ‘sql’, ‘x’, ‘fn’ vì chúng được cộng đồng sử dụng rộng rãi, giúp tránh nhầm lẫn.
Các thẻ cốt lõi của JSTL được liệt kê trong bảng bên dưới.
| Thẻ JSTL Core | Mô tả |
|---|---|
<c:out> |
Dùng để xuất dữ liệu ra trang JSP, có thể sử dụng biểu thức EL kèm theo thẻ này. |
<c:import> |
Tương tự như jsp:include hoặc chỉ thị include. |
<c:redirect> |
Chuyển hướng yêu cầu tới một tài nguyên khác. |
<c:set> |
Dùng để gán giá trị cho một biến trong phạm vi xác định. |
<c:remove> |
Dùng để xóa biến khỏi phạm vi xác định. |
<c:catch> |
Bắt ngoại lệ và đóng gói nó vào một đối tượng. |
<c:if> |
Cấu trúc điều kiện đơn giản, sử dụng cùng với EL và có thể dùng để xử lý ngoại lệ từ <c:catch>. |
<c:choose> |
Thẻ điều kiện tổng quát, thiết lập ngữ cảnh cho các điều kiện loại trừ lẫn nhau, được đánh dấu bởi <c:when> và <c:otherwise>. |
<c:when> |
Thẻ con của <c:choose>, phần thân của nó sẽ được thực thi nếu điều kiện là true. |
<c:otherwise> |
Thẻ con của <c:choose>, phần thân sẽ được thực thi nếu tất cả các điều kiện <c:when> đều là false. |
<c:forEach> |
Dùng để lặp qua một tập hợp (collection). |
<c:forTokens> |
Dùng để lặp qua các token được phân tách bởi dấu phân cách. |
<c:param> |
Dùng với <c:import> để truyền tham số. |
<c:url> |
Dùng để tạo URL với các tham số truy vấn tùy chọn. |
Thực hành với JSTL Core Tags
Để hiểu rõ hơn về cách sử dụng JSTL core tags, chúng ta sẽ xây dựng một ứng dụng web đơn giản. Dự án sẽ bao gồm một Java Bean, Trang JSP sẽ minh họa cách lặp qua một collection, sử dụng logic điều kiện với EL và một số cách sử dụng phổ biến khác.

Lớp Java Bean
Đầu tiên, chúng ta có một lớp Employee đơn giản:
package com.journaldev.model;
public class Employee {
private int id;
private String name;
private String role;
public Employee() {
}
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 String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
Lớp Servlet điều khiển
Tiếp theo, HomeServlet sẽ tạo một danh sách các đối tượng Employee, đặt chúng cùng với một số thuộc tính khác vào request scope và chuyển tiếp đến trang JSP.
package com.journaldev.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
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 com.journaldev.model.Employee;
@WebServlet("/HomeServlet")
public class HomeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Employee> empList = new ArrayList<Employee>();
Employee emp1 = new Employee();
emp1.setId(1); emp1.setName("Pankaj");emp1.setRole("Developer");
Employee emp2 = new Employee();
emp2.setId(2); emp2.setName("Meghna");emp2.setRole("Manager");
empList.add(emp1);empList.add(emp2);
request.setAttribute("empList", empList);
request.setAttribute("htmlTagData", "<br/> creates a new line.");
request.setAttribute("url", "<https://www.journaldev.com>");
RequestDispatcher rd = getServletContext().getRequestDispatcher("/home.jsp");
rd.forward(request, response);
}
}
Trang JSP hiển thị
Và đây là nội dung của home.jsp, nơi chúng ta sẽ sử dụng các JSTL core tags để hiển thị dữ liệu và thực hiện các logic khác nhau:
<%@ page language="java" contentType="text/html; charset=US-ASCII"
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<https://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Home Page</title>
<%@ taglib uri="<https://java.sun.com/jsp/jstl/core>" prefix="c" %>
<style>
table,th,td
{
border:1px solid black;
}
</style>
</head>
<body>
<%-- Using JSTL forEach and out to loop a list and display items in table --%>
<table>
<tbody>
<tr><th>ID</th><th>Name</th><th>Role</th></tr>
<c:forEach items="${requestScope.empList}" var="emp">
<tr><td><c:out value="${emp.id}"></c:out></td>
<td><c:out value="${emp.name}"></c:out></td>
<td><c:out value="${emp.role}"></c:out></td></tr>
</c:forEach>
</tbody>
</table>
<br><br>
<%-- simple c:if and c:out example with HTML escaping --%>
<c:if test="${requestScope.htmlTagData ne null }">
<c:out value="${requestScope.htmlTagData}" escapeXml="true"></c:out>
</c:if>
<br><br>
<%-- c:set example to set variable value --%>
<c:set var="id" value="5" scope="request"></c:set>
<c:out value="${requestScope.id }" ></c:out>
<br><br>
<%-- c:catch example --%>
<c:catch var ="exception">
<% int x = 5/0;%>
</c:catch>
<c:if test = "${exception ne null}">
<p>Exception is : ${exception} <br>
Exception Message: ${exception.message}</p>
</c:if>
<br><br>
<%-- c:url example --%>
<a href="<c:url value="${requestScope.url }"></c:url>">JournalDev</a>
</body>
</html>
Bây giờ khi chúng ta chạy ứng dụng với URL https://localhost:8080/JSTLExample/HomeServlet, chúng ta sẽ nhận được phản hồi như hình ảnh bên dưới.

Tóm lại, những gì chúng ta cần ghi nhớ về JSTL là sự linh hoạt và sức mạnh mà nó mang lại cho các trang JSP.
Kết luận
Chúng ta đã cùng nhau đi qua một hành trình khám phá JSTL một công cụ vô cùng mạnh mẽ, biến việc phát triển các ứng dụng web Java trở nên dễ dàng và hiệu quả hơn. Việc nắm vững JSTL sẽ nâng cao đáng kể kỹ năng phát triển web Java của bạn, giúp bạn xây dựng các ứng dụng mạnh mẽ, dễ bảo trì và có hiệu suất cao hơn.