JavaServer Pages
| JSP | |
|---|---|
| Расширение |
.jsp |
| MIME-тип | application/jsp |
| Разработчик | Eclipse Foundation |
| Последний выпуск | 3.1.0 (15 мая 2022) |
| Тип формата | формат файла, Шаблонизатор и техническая спецификация[вд] |
| Стандарт(ы) | JSR 245 |
| Сайт | projects.eclipse.org/… (англ.) |
JSP (JavaServer Pages) — платформенно-независимая, переносимая и легко расширяемая технология для разработки веб-приложений, работающая на виртуальной машине Java (JVM). JSP позволяет веб-разработчикам создавать содержимое, состоящее из статических исходных данных, которые могут быть оформлены в одном из текстовых форматов HTML, SVG, WML, или XML, и JSP-элементов, которые конструируют динамическое содержимое. Кроме этого могут использоваться библиотеки JSP-тегов, а также Expression Language (EL), для внедрения Java-кода в статичное содержимое JSP-страниц.
Код JSP-страницы транслируется в Java-код сервлета с помощью компилятора JSP-страниц Jasper, затем компилируется в байт-код Java, после чего сервлет может быть запущен в контейнерах сервлетов. JSP-страницы загружаются на сервере и управляются из структуры специального Java server packet, который называется Jakarta EE Web Application. Обычно страницы упакованы в файловые архивы .war и .ear.
Версии
[править | править код]Начиная с версии 1.2, разработка JavaServer Pages происходила в рамках Java Community Process. JSR 53 определяет стандарты JSP 1.2 и Servlet 2.3, а JSR 152 определяет спецификацию JSP 2.0. В мае 2006 года JSP спецификация 2.1 была выпущена под JSR 245 в рамках Java EE 5. 10 декабря 2009 года была выпущена спецификация JSP 2.2 как содержание выпуска JSR 245.
JSP 1.0 и JSP 1.1
[править | править код]Эти версии кардинально отличаются от предыдущих, которые воспринимались как ответ Java на ASP. Некоторые основные возможности прошлых версий (например, возможность разрабатывать библиотеки тегов) были убраны или заменены в соответствии с принципом разделения кода и содержимого. Так как в больших объёмах исходного кода трудно сориентироваться и отделить контент от самого кода, то пришла идея их разделить (перенести) с помощью JSP тегов, таких как <jsp:useBean/>. Для реализации этой идеи JSP-теги разделили на три логические группы: директивы, скриптовые элементы и действия.
JSP 1.2
[править | править код]JSP 1.2 расширяет спецификацию JavaServer Pages 1.1 (JSP 1.1) следующим образом:
- требуют платформы Java 2 версии 1.2 или более поздней;
- использует Servlet 2.3 как основу своей семантики;
- определяет синтаксис XML для страниц JSP;
- предоставляет проверку страниц JSP на этапе трансляции;
- специфицирует очистку библиотеки тегов на этапе прогона;
- улучшает контракт обработчика тегов;
- предоставляет улучшенную поддержку авторизации страниц;
- улучшает поддержку кодировки символов и локализации;
- устраняет ограничение «flush before you include» из JSP 1.1.
JSP 2.0
[править | править код]Новая версия спецификации JSP дополнена следующей функциональностью:
- Expression Language (EL) — язык выражений, позволяет среди прочего создавать разработчикам шаблоны в стиле Velocity;
- более простой и быстрый способ создавать новые теги с помощью файлов
.tag, теперь для создания новых тегов не обязательно знать Java; - удобный способ управления вложенными бинами (JavaBeans);
- более быстрый и лёгкий способ отображения параметров переменных:
Hello, ${param.visitor} <%-- аналогично коду: Hello, <%=request.getParameter("visitor")%> --%>
JSP 2.1
[править | править код]- аключает в себя JSTL и JavaServer Faces;
- новая версия EL поддерживает отложенное исполнение выражений и литеральные выражения, а также J5EE enumeration.
Платформа Java EE 5 фокусируется на простой разработке с использованием языковых аннотаций Java, которые были введены J2SE 5.0. JSP 2.1 поддерживает эту цель определением аннотаций для зависимых инъекций в JSP операторах и в контекстных слушателях (Listeners).
Обзор
[править | править код]JavaServer Pages (JSP) позволяют отделить динамическую часть страниц от статического HTML. Динамическая часть заключается в специальные теги "<% %>":
Имя вашего хоста: <%= request.getRemoteHost() %>
JSP страницы имеют расширение .jsp и размещаются там же, где и обычные Web-страницы. Структура таких страниц может состоять из пяти конструкций: HTML, комментарии, скриптовые элементы, директивы и действия. JSP-страница при компиляции преобразуется в сервлет со статическим содержимым, которое направляется в поток вывода, связанный с методом service. Поэтому при первом запросе этот процесс может вызвать небольшую задержку. Комментарии в документе или программе не являются причиной замедления программы, так как транслятор и исполнитель их игнорируют. Скриптовые элементы позволяют указать код на языке Java, который впоследствии станет частью конечного сервлета, директивы дают возможность управлять всей структурой сервлета, а действия служат для задания существующих используемых компонентов и также для контроля над поведением движка JSP. Для упрощения работы со скриптами имеются заранее определённые переменные, такие как request, response, pageContext, session, out, application, config, page, exception.
Пример JSP страницы с использованием всех составляющих JSP:
Комментарии
[править | править код]Комментарии используются для пояснения исходного текста программы. В JSP-страницах комментарии можно разделить на две группы:
- комментарии исходного кода JSP;
- комментарии HTML-разметки.
Комментарии исходного кода JSP отмечаются специальной последовательностью символов: <%-- в начале и --%> в конце комментария. Данный вид комментариев удаляется на этапе компиляции JSP-страницы. Пример JSP-комментария:
<%--
Отобразит каталог изделий
и актуальную корзину покупателя.
--%>
Комментарии HTML-разметки оформляются в соответствии с правилами языка HTML. Данный вид комментариев рассматривается JSP-компилятором как статический текст и помещается в выходной HTML-документ. JSP-выражения внутри HTML-комментариев исполняются. Пример HTML-комментария:
<!-- Дата создания страницы: <%= new java.util.Date() %> -->
Скриптовые элементы
[править | править код]Спецификация JSP различает три типа скриптовых элементов:
- объявления
<%!одна или несколько деклараций%>; - выражения
<%=одно выражение%>; - скриплеты
<%скриплет%>.
Объявления обычно используются для определения переменных, методов, внутренних классов и остальных действующих Java конструкций на уровне класса. Выражения становятся аргументами для метода out.print(). С помощью скриплетов в JSP страницы вкладываются работающие части Java-кода.
Объявления JSP
[править | править код]Объявления JSP позволят вам задавать переменные, методы, внутренние классы и так далее. Объявления используются для определения используемых в программе конструкций Java. Так как объявления не осуществляют вывода, обычно они используются совместно с JSP-выражениями или скриплетами. В приведённом в качестве примера фрагменте JSP отображается количество запросов к данной странице с момента загрузки сервера (или с момента последнего изменения и перезагрузки сервлета). Обратите внимание, что в примере мы используем как объявление, так и выражение и что внутри конструкции после объявления стоит точка с запятой (;):
<%! private int accessCount = 0; %>
Количество обращений к странице с момента загрузки сервера: <%= ++accessCount %>
Выражения JSP
[править | править код]Выражения JSP применяются для того, чтобы вставить значения Java непосредственно в вывод. Выражения Java вычисляются, конвертируются в строку и вставляются в страницу. Эти вычисления проходят во время выполнения (то есть при запросе страницы), а потому существует полный доступ к информации о самом запросе.
В выражениях можно использовать постоянные, переменные, вызовы различных методов. Все выражения, вне зависимости от сложности их содержимого, вычисляются в один результат или число. JSP страницы полагаются на JSP Writer, который берёт любой результат выражения, переводит его в тип String (текстовый) и заносит в буферную память. Например, следующий код служит для отображения даты и времени запроса данной страницы:
Текущее время: <%= new java.util.Date() %>
Имя вашего хоста: <%= request.getRemoteHost() %>
Необходимо обратить внимание на три правила:
- JSP выражения должны в себе содержать выражения Java.
- Каждое JSP выражение должно содержать только одно выражение Java.
- Выражения JSP обязаны не заканчиваться точкой с запятой (
;), в отличие от Java объявлений.
Скриплеты JSP
[править | править код]Скриплеты JSP дают возможность вставить любой код в метод сервлета, который будет создан при обработке страницы, позволяя использовать большинство конструкций Java. Скриплеты также имеют доступ к тем же заранее определённым переменным, что и выражения. Поэтому, например, для вывода значения на страницу необходимо использовать заранее определённую переменную out.
<%
String queryData = request.getQueryString();
out.println("Дополнительные данные запроса: " + queryData);
%>
Код внутри скриплета вставляется в том виде, как он был записан. Весь статический HTML (текст шаблона) до или после скриплета конвертируется при помощи оператора print. Например, следующий фрагмент JSP содержит смешанный текст шаблона и скриплета:
<% if (Math.random() < 0.5) { %>
<B>Удачного</B> вам дня!
<% } else { %>
<B>Неудачного</B> вам дня!
<% } %>
После преобразования скриплета код будет выглядеть следующим образом:
if (Math.random() < 0.5) {
out.println("<B>Удачного</B> вам дня!");
} else {
out.println("<B>Неудачного</B> вам дня!");
}
Это означает, что скриплеты не обязательно должны содержать завершённые фрагменты Java, и что оставленные открытыми блоки могут оказать влияние на статический HTML вне скриплета.
Директивы JSP
[править | править код]JSP страница может послать сообщение соответствующему контейнеру с указаниями действий, которые необходимо провести. Эти сообщения называются директивами. Все директивы начинаются с <%@, затем следует название директивы и один или несколько атрибутов со значениями, и заканчиваются %>. Директивы в JSP странице приводят к тому, что контейнер пошлёт заявку на исполнение определённой службы, которая в генерированном документе не объявляется. Форму записи директив можно изобразить следующим образом:
<%@ директива атрибут="значение" %>
Вы также можете объединить установку нескольких атрибутов для одной директивы:
<%@ директива атрибут1="значение1"
атрибут2="значение2"
...
атрибутN="значениеN" %>
Существует три основных типа директив: page, которая позволяет вам совершать такие операции, как импорт классов, изменение суперкласса сервлета, и т. п.; include, которая даёт вам возможность вставить файл в класс сервлета при трансляции JSP файла в сервлет; и taglib, позволяющий расширить множество тегов своими собственными, которые JSP контейнер способен истолковать.
Директива JSP page
[править | править код]Как можно догадаться из названия, данная директива предоставляет атрибуты для JSP страницы. Атрибуты, определённые в этой директиве, внедряются в данную JSP страницу и на все её вложенные статические элементы, независимо от того, были ли они вставлены с помощью директивы include или с помощью действия jsp:include. Форма записи директивы page следующая:
<%@ page атрибут=“значение“ %>
В качестве примера приведём следующую запись:
<%@ page import=”java.util.*, com.myclasses.*” buffer=”15kb” %>
Эта директива заявляет, что JSP страница импортирует классы из двух пакетов Java, java.util и com.myclasses, а потом уточняет размер буферной памяти, которая должна быть использована для обработки данной JSP страницы.
Далее рассмотрим атрибуты директивы page:
import="пакет.class1, пакет.class2, ..., пакет.classN".Позволяет вам задать пакеты, которые должны быть импортированы. Это единственный атрибут, который может использоваться несколько раз в одной директиве. В список необходимо включить все классы Java, которые Вы хотите использовать и которые не являются частью исходного набора импортируемых классов. Исходный набор содержит:java.lang.*, javax.servlet.*, javax.servlet.jsp.* и javax.servlet.http.*.Пример использования атрибутаimport:
<%@ page import="java.util.Date, javax.text.SimpleDateFormat, com.myclasses.*" %>
language="java".Данный атрибут предназначен для задания используемого языка программирования. По умолчанию принимается значение"java". Этот атрибут необязательно использовать, но тем не менее проблема потом может наступить в случае, если поставщик JSP контейнера будет использовать другие языки (например, JavaScript). Пример записи данного атрибута следующий:
<%@ page language=”java” %>
extends="пакет.class".Задаёт суперкласс (родительский класс) для генерируемого сервлета. Обычно сервлет возникает расширением исходного класса. Опытные программисты могут с помощью этого атрибута создавать собственные суперклассы. Пример использования этого атрибута может выглядеть следующим образом:
<%@ page extends=”myPackage.HttpExample” %>
session="true|false".Данный атрибут может принимать значение true или false, которые определяют принимает ли участие JSP страница в трансляции HTTP. Значениеtrue(«истина», принимается по умолчанию) сигнализирует о том, что заранее определённая переменнаяsession(типHttpSession) должна быть привязана к существующей сессии, если таковая имеется, в противном случае создаётся новая сессия, к которой и осуществляется привязка. Значениеfalse(«ложь») определяет, что сессии не будут использоваться, и попытки обращения к переменнойsessionприведут к возникновению ошибки при трансляции JSP страницы в сервлет. Пример использования данного атрибута может выглядеть следующим образом:
<%@ page session=”false” %>
buffer="размерkb|none".Данный атрибут задаёт объём буферной памяти, необходимой для объекта JspWriter, на который ссылается заранее определённая переменнаяout. Значение, принимаемое по умолчанию, зависит от настроек сервера, но должно превышать8kb. Значение задаётся либо в форме «размерkb» либо «none». Если Вы укажете значение буферной памяти какnone, то сервлет не будет ничего сохранять в буферную память и передаст результат, записанный до переменнойout, прямо объектуPrintWriter, который предоставляется вместе с объектомServletResponse.Если Вы зададите значение буферной памяти на конкретную величину, тоJspWriterбудет в эту память сохранять данные, в результате чего увеличится производительность. В отличие от объектаPrintWriterобъектJspWriterможет вызывать исключительные ситуацииIOExceptions. Исходная величина буферной памяти равна8kB. Пример записи данного атрибута может выглядеть следующим образом:
<%@ page buffer=”12kb” %>
autoflush="true|false".Данный атрибут может принимать значения true или false. Значениеtrue(«истина», принимаемое по умолчанию) устанавливает, что при переполнении буферной памяти он автоматически очистится. Значениеfalse(«ложь»), которое крайне редко используется, устанавливает что переполнение буфера должно приводить к возникновению исключительной ситуации (IOExceptions). Обычно атрибутыbufferиautoflushустанавливаются вместе в одной директиве. При установке значение атрибутаbuffer="none"установка значенияfalseдля атрибутаautoflushнедопустима. Пример может выглядеть следующим образом:
<%@ page buffer=”16kb” autoflush=”true” %>
isThreadSafe="true|false".Данный атрибут может принимать значения true или false. Значениеtrue(«истина», принимается по умолчанию) задаёт нормальный режим выполнения сервлета, когда множественные запросы обрабатываются одновременно с использованием одного экземпляра сервлета, исходя из соображения что автор синхронизировал доступ к переменным этого экземпляра. Значениеfalse(«ложь») сигнализирует о том, что сервлет должен наследоватьSingleThreadModel(однопоточную модель), при которой последовательные или одновременные запросы обрабатываются отдельными экземплярами сервлета. Другими словами значениеtrueприведёт к тому, что контейнер может посылать сервлету сразу несколько запросов, в то время как при значенииfalseконтейнер посылает запросы по одному. Пример использования выглядит так:
<%@ page isThreadSafe=”false” %>
info="информация".Задаёт строку, которая может быть получена при использовании методаServlet.getServletInfo().Обычно этот метод возвращает информацию о сервлете (например, авторе, версии и авторских правах). Пример записи данного атрибута может выглядеть следующим образом:
<%@ page info=”Автор: Пётр Иванович; версия:1.0” %>
errorPage="url".Задаёт JSP страницу, которая вызывается в случае возникновения каких-либо событийThrowables, которые не обрабатываются на данной странице. Если на JSP странице случится исключение, и JSP страница не имеет собственного кода для решения этого исключения, то контейнер автоматически передаст управление на URL, которую Вы задали в качестве значения атрибутаerrorPage. Пример записи выглядит так:
<%@ page errorPage=“/myweb/errors/myerror.jsp“ %>
isErrorPage="true|false".Данный атрибут может принимать значения true или false. Сигнализирует о том, может ли эта страница использоваться для обработки ошибок для других JSP страниц или нет. По умолчанию принимается значениеfalse(«ложь»). Пример использования данного атрибута может выглядеть следующим образом:
<%@ page isErrorPage=”true” %>
contentType="MIME-Тип".Данный атрибут задаёт типMIMEдля вывода и по желанию можно задать кодировку знаков в ответе (HTML ответе). По умолчанию в качестве значенияMIMEиспользуетсяtext/html. Для наглядности можем использовать следующий пример:
<%@ page contentType="text/plain" %>
Того же результата можно добиться и использованием скриплета:
<% response.setContentType("text/plain"); %>
Директива JSP include
[править | править код]Эта директива позволяет Вам включать файлы в сервлет в процессе трансляции JSP страницы. Использование директивы выглядит следующим образом:
<%@ include file="относительный url" %>
Заданный URL обычно интерпретируется относительно JSP страницы, на которой расположена ссылка, но, как и при использовании любых других относительных URL вы можете задать системе положение интересующего вас ресурса относительно домашнего каталога Web сервера, добавив в начало URL символ «/». Содержимое подключаемого файла обрабатывается как обычный текст JSP и поэтому может включать такие элементы как статический HTML, элементы скриптов, директивы и действия.
Например, многие сайты используют небольшую панель навигации на каждой странице. В связи с проблемами использования фреймов HTML часто эта задача решается размещением небольшой таблицы сверху или в левой половине страницы, HTML код которой многократно повторяется для каждой страницы сайта. Директива include наиболее естественный способ решения этой задачи, избавляющий разработчика от кошмара рутины копирования HTML в каждый отдельный файл. Это происходит следующим образом: