8. Бібліотека тегів JSTL
8.0.1. Вступ
Розглянемо вікно [erreurs.jsp], яке відображає список помилок:

Існує кілька способів написання такої сторінки. Тут нас цікавить лише частина, що стосується відображення помилок. Перший варіант — використання коду Java, як це було зроблено:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
<%
// отримуємо дані з моделі
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<%
for(int i=0;i<erreurs.size();i++){
out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
}//for
%>
</ul>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
<%= lienRetourFormulaire %>
</a>
</body>
</html>
Сторінка JSP отримує список помилок із запиту (рядок 8) і відображає його за допомогою циклу Java (рядки 19–23). На цій сторінці поєднуються код HTML та Java-код, що може стати проблемою, якщо обслуговуванням сторінки займатиметься веб-дизайнер, який, як правило, не розуміє Java-коду. Щоб уникнути такого поєднання, використовуються бібліотеки тегів, які надають нові можливості для сторінок JSP. Завдяки бібліотеці тегів JSTL (Java Standard Tag Library) попередній вигляд стає таким:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<c:forEach var="erreur" items="${erreurs}">
<li>${erreur}</li>
</c:forEach>
</ul>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
Тег (рядок 4)
вказує на використання бібліотеки тегів, визначення якої міститься у файлі [/WEB-INF/c.tld]. Ці теги будуть використовуватися в коді сторінки з префіксом «c» (prefix="c"). Можна використовувати будь-який префікс на власний вибір. У цьому випадку «c» означає [core]. Префікси дають змогу використовувати бібліотеки тегів, у яких деякі теги можуть мати однакові назви. Використання префікса усуває неоднозначність. На новій сторінці більше немає коду Java у двох місцях, де він був раніше:
- завантаження шаблону сторінки [erreurs, lienRetourFormulaire] (вилучена частина)
- відображення списку помилок (рядки 13–15)
Цикл відображення помилок було замінено на такий код:
<c:forEach var="erreur" items="${erreurs}">
<li>${erreur}</li>
</c:forEach>
- тег <forEach> використовується для обмеження циклу
- Запис ${variable} використовується для вказівки значення змінної
Тег <forEach> має тут два атрибути:
- items="${erreurs}" вказує на колекцію об’єктів, по якій потрібно виконати ітерацію. У цьому випадку колекцією є об’єкт erreurs. Де його можна знайти? Сторінка JSP послідовно шукає атрибут із назвою «erreurs» у такому порядку:
- об’єкті [request], який представляє запит, переданий контролером: request.getAttribute("erreurs")
- об’єкті [session], який представляє сесію клієнта: session.getAttribute("помилки")
- об’єкт [application], який представляє контекст веб-додатку: application.getAttribute("помилки")
Колекція, позначена атрибутом items, може мати різні форми: tableau, ArrayList, об’єкт, що реалізує інтерфейс List, ...
- var="помилка" слугує для присвоєння імені поточному елементу колекції, що обробляється. Цикл <forEach> буде послідовно виконуватися для кожного елемента колекції items. Усередині циклу елемент колекції, що обробляється, буде позначений як помилка.
Запис ${erreur} вставляє значення змінної «erreur» у текст. Ця змінна не обов’язково є рядком символів. JSTL використовує метод erreur.toString() для вставки значення змінної «erreur». Замість запису ${помилка} також можна використовувати тег <c:out value="${помилка}"/>.
Повертаючись до нашого прикладу відображення помилок:
- контролер додасть до запиту, що передається на сторінку JSP, ArrayList повідомлень про помилки, тобто ArrayList об’єктів String: request.setAttribute("помилки",помилки), де «помилки» — це ArrayList;
- через атрибут items="${помилки}" сторінка JSP шукатиме атрибут з назвою «помилки» послідовно у запиті, сесії та додатку. Вона знайде його у запиті: request.getAttribute("помилки") поверне ArrayList, розміщений у запиті контролером;
- отже, змінна erreur атрибута var="erreur" буде вказувати на поточний елемент ArrayList, тобто на об’єкт String. Метод erreur.toString() вставив значення цього String, у даному випадку повідомлення про помилку, у потік HTML сторінки.
Об’єкти колекції, що обробляються тегом <forEach>, можуть бути складнішими, ніж прості рядки символів. Розглянемо приклад сторінки JSP, яка відображає список статей:
де [listarticles] — це ArrayList об’єктів типу [Article], які, як припускається, є Javabean із полями [id, nom, prix, stockActuel, stockMinimum], кожне з яких має свої методи get та set. Об’єкт [listarticles] був доданий до запиту контролером. Попередня сторінка JSP отримає його в атрибуті items тегу forEach. Отже, поточний об’єкт article (var="article") позначає об’єкт типу [Article]. Розглянемо тег у рядку 3:
Що означає ${article.nom}? Насправді це може означати різні речі залежно від типу об’єкта «стаття». Щоб отримати значення article.nom, сторінка JSP спробує виконати дві дії:
- article.getNom() — зверніть увагу на написання getNom для отримання поля «ім’я» (стандарт JavaBean)
- article.get("nom")
Отже, об’єкт [article] може бути біном із полем «nom» або словником із ключем «nom».
Немає обмежень щодо ієрархії оброблюваного об’єкта. Таким чином, тег
дозволяє обробляти об’єкт [individu] такого типу:
class Individu{
private String nom;
private String prénom;
private Individu[] enfants;
// методи стандарту JavaBean
public String getNom(){ return nom;}
public String getPrénom(){ return prénom;}
public Individu getEnfants(int i){ return enfants[i];}
}
Щоб отримати значення ${individu.enfants[1].nom}, сторінка JSP спробує різні методи, серед яких цей, що дасть результат:
individu.getEnfants(1).getNom(), де «individu» позначає об’єкт типу «Individu».
8.0.2. Встановлення та ознайомлення з бібліотекою JSTL
Наведених вище пояснень буде достатньо для програми, яка нас цікавить, але бібліотека тегів JSTL пропонує й інші теги, крім представлених. Щоб ознайомитися з ними, можна встановити навчальний посібник, що входить до пакету бібліотеки.
Ми використовуватимемо реалізацію JSTL 1.1 проекту [Jakarta Taglibs], доступну за адресою [http://jakarta.apache.org/taglibs/] (травень 2006 року):
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
Завантажений zip-файл містить приблизно такий вміст:

Два файли з розширенням .war є архівами веб-додатків:
- standard-doc: документація щодо тегів JSTL
- standard-examples: приклади використання тегів
Ми розгорнемо останній додаток у середовищі Tomcat. Запускаємо його за допомогою відповідної опції в меню [Démarrer], потім вводимо URL-адресу [http://localhost:8080] і переходимо за посиланням [Tomcat Manager]:

Після цього з’являється сторінка входу. Ми входимо під обліковими даними manager / manager або admin / admin, як показано в розділі 2.3.3.

Ми потрапляємо на сторінку зі списком додатків, які наразі розгорнуті в Tomcat:

Ми можемо додати новий додаток за допомогою форм, розміщених у нижній частині сторінки:

Ми використовуємо кнопку [Parcourir], щоб вказати файл .war для розгортання.

На знімку екрана цього не видно, але ми вибрали файл [standard-examples.war] із завантаженого дистрибутива JSTL. Кнопка [Deploy] зберігає та розгортає цей додаток у Tomcat.

Додаток [/standard-examples] було успішно розгорнуто. Запускаємо його:

Читачеві пропонується перейти за різними посиланнями, наведеними на цій сторінці, якщо він шукає приклади використання тегів JSTL.
Додаток [standard-doc] можна розгорнути таким самим чином на основі файлу [standard-doc.war]. Він надає доступ до досить технічної інформації про бібліотеку JSTL. Для початківців він представляє менший інтерес.
8.0.3. Використання JSTL у веб-додатку
У прикладах, що постачаються разом із бібліотекою JSTL 1.2, сторінки JSP містять на початку файлу такий тег:
Ми вже зустрічали цей тег у розділі 8.1.1 і навели коротке пояснення:
- [uri]: URI (Uniform Resource Identifier), де міститься визначення тегів, що використовуються на сторінці. Цей тег URI буде використовуватися веб-сервером, коли сторінка JSP буде перетворена на код Java для створення сервлету. Він також використовується інструментами розробки веб-сторінок для перевірки правильності синтаксису тегів, що використовуються на сторінці, або для надання підказки під час введення. Коли користувач починає вводити тег, інструмент, який знає бібліотеку, може запропонувати йому можливі атрибути для цього тегу.
- [prefix]: префікс, що ідентифікує ці теги на сторінці
URI [http://java.sun.com/jsp/jstl/core] не можна використовувати, якщо немає підключення до загальнодоступного Інтернету. У цьому випадку файл з визначеннями тегів можна розмістити локально. Кілька таких файлів надаються разом із дистрибутивом JSTL 1.2 у папці [tld] (Tag Language Definition):

JSTL — це, по суті, набір бібліотек тегів. Ми будемо використовувати лише бібліотеку [c.tld], так звану «основну» бібліотеку. Ми розмістимо файл [c.tld], наведений вище, у папці [WEB-INF] наших додатків:
![]()
та додамо на наших сторінках тег JSP, щоб вказати використання бібліотеки «core»:
Хоча використання бібліотек тегів дозволяє нам уникнути вставки коду Java на сторінки JSP, ці теги, звичайно, перетворюються на код Java під час перетворення сторінки JSP у Java-сервлет. Вони використовують класи, визначені у двох архівах [jstl.jar, standard.jar], які містяться у папці [lib] дистрибутива JSTL:

Ці два архіви розміщені у папці [WEB-INF/lib] наших додатків:

Тепер ми маємо основу для розробки наступної версії нашого прикладу додатка.





