Избавляемся от Java-кода в JSP: 3 мощных подхода JSP 2

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Прощай, спагетти-код: как вычистить Java из JSP раз и навсегда

Если вы когда-нибудь открывали старый JSP-файл и видели мешанину из HTML, <% %> скриптлетов и логики на Java, вы знаете это чувство. Смесь презентации и бизнес-логики превращает поддержку проекта в ад. Вопрос "How can I avoid Java code in JSP files, using JSP 2?" на Stack Overflow набрал тысячи просмотров — и не зря.

Хорошая новость: JSP 2 (Java Server Pages версии 2) дал нам инструменты, чтобы навсегда забыть о скриптлетах. В этой статье я покажу три реальных подхода, которые превратят ваши JSP в чистые, читаемые шаблоны. Никакой воды — только код и практика.

Почему скриптлеты — зло? Взгляд разработчика

Скриптлеты (эти самые <% ... %>) нарушают главный принцип MVC: разделение логики и представления. Вот три причины, почему от них нужно избавляться:

  • Сложность поддержки. Когда в JSP есть SQL-запросы и условные операторы, дизайнер не может безопасно править верстку.
  • Трудное тестирование. Логику внутри JSP невозможно протестировать unit-тестами.
  • Плохая читаемость. Код превращается в "спагетти", где Java мешается с HTML.

JSP 2 предлагает элегантные альтернативы. Давайте разберем их на примере реальной задачи: вывод списка пользователей из базы данных.

Подход 1: Expression Language (EL) — ваш новый друг

Expression Language (EL) позволяет обращаться к Java-объектам прямо в JSP без единой строчки Java-кода. Синтаксис ${...} интуитивно понятен.

Было (с Java-кодом):

<% 
    User user = (User) request.getAttribute("user"); 
    out.println("Привет, " + user.getName());
%>

Стало (с EL):

<p>Привет, ${user.name}</p>

EL автоматически вызывает геттеры. Если user.getName() возвращает строку — она подставится в HTML. Если объект равен null — EL просто ничего не выведет (без NullPointerException).

Где использовать: для вывода данных из request, session, application scope или параметров запроса.

Подход 2: JSTL (JSP Standard Tag Library) — циклы и условия без Java

JSTL — это набор готовых тегов, которые покрывают 90% типовых задач: циклы, условия, форматирование, работа с URL. Для подключения достаточно добавить зависимость в pom.xml (Maven) или скачать JAR.

Пример: выводим список пользователей в таблицу.

До (скриптлеты):

<table>
    <%
        List<User> users = (List<User>) request.getAttribute("users");
        for (User u : users) {
    %>
        <tr><td><%= u.getName() %></td><td><%= u.getEmail() %></td></tr>
    <%
        }
    %>
</table>

После (JSTL + EL):

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<table>
    <c:forEach var="u" items="${users}">
        <tr>
            <td>${u.name}</td>
            <td>${u.email}</td>
        </tr>
    </c:forEach>
</table>

Обратите внимание: ни одной строчки Java! Тег <c:forEach> работает как foreach-цикл, а ${u.name} — это EL-выражение. Код стал читаемым и безопасным.

Другие полезные теги JSTL:

  • <c:if test="${condition}"> — условный вывод
  • <c:choose> — аналог switch
  • <c:set var="x" value="..." /> — создание переменной
  • <fmt:formatDate> — форматирование дат

Подход 3: Custom Tags (пользовательские теги) — для сложной логики

Если JSTL не хватает, можно создать собственный тег. Это мощный инструмент, когда нужно вынести повторяющуюся логику в отдельный компонент.

Пример: тег, который выводит "Hello, имя!" с проверкой на null.

Шаг 1. Создаем класс тега (Java):

package com.example.tags;

import javax.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspException;
import java.io.IOException;

public class HelloTag extends SimpleTagSupport {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void doTag() throws JspException, IOException {
        String output = (name != null) ? "Hello, " + name + "!" : "Hello, Guest!";
        getJspContext().getOut().write(output);
    }
}

Шаг 2. Описываем тег в TLD-файле (например, /WEB-INF/tags.tld):

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
        version="2.1">
    <tlib-version>1.0</tlib-version>
    <short-name>mytags</short-name>
    <tag>
        <name>hello</name>
        <tag-class>com.example.tags.HelloTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>name</name>
            <required>false</required>
        </attribute>
    </tag>
</taglib>

Шаг 3. Используем в JSP:

<%@ taglib uri="/WEB-INF/tags.tld" prefix="mytags" %>
<p><mytags:hello name="${user.name}" /></p>

Результат: в JSP нет Java, вся логика — в отдельном классе. Это идеальный пример соблюдения

Блоги

Рекомендаций по книгам