Смотреть что такое "JSP" в других словарях. Java Server Page. Введение

JSP (JavaServer Pages ) - технология, позволяющая веб-разработчикам легко создавать содержимое, которое имеет как статические, так и динамические компоненты. По сути, страница JSP является текстовым документом, который содержит текст двух типов: статические исходные данные, которые могут быть оформлены в одном из текстовых форматов HTML , SVG , WML , или XML , и JSP элементы, которые конструируют динамическое содержимое. Кроме этого могут использоваться библиотеки JSP тегов, а также (Expression Language), для внедрения Java-кода в статичное содержимое JSP-страниц.

JSP - одна из высокопроизводительных технологий, так как весь код страницы транслируется в java-код сервлета с помощью компилятора JSP страниц Jasper , и затем компилируется в байт-код виртуальной машины java (JVM). Контейнеры сервлетов , способные исполнять JSP страницы, написаны на языке Java, который может работать на различных платформах. JSP страницы загружаются на сервере и управляются из структуры специального Java server packet, который называется Java EE Web Application, в большинстве своём упакованные в файловые архивы .war и .ear .

Выгода, которую дает технология JSP в сравнении с другими веб-технологиями заключается в том, что JSP является платформонезависимой, переносимой и легко расширяемой технологией для разработки веб-приложений.

Версии

Начиная с версии 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 теги разделили на три логические группы: директивы, скриптовые элементы и действия.

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 }

JSP 2.1
  • Включает в себя JSTL и JavaServer Faces ;
  • Новая версия поддерживает отложенное исполнение выражений и литеральные выражения, а также J5EE enumeration.

Платформа Java EE 5 главным образом фокусируется на простую разработку используя языковые аннотации Java, которые были введены J2SE 5.0 . JSP 2.1 поддерживает эту цель определением аннотаций для зависимых инъекций в JSP операторах и в контекстных слушателях (Listeners).

Обзор

JavaServer Pages (JSP) позволяют отделить динамическую часть страниц от статического HTML . Процедура довольно проста, создаёте обычный код HTML (статический), а динамическую часть заключаете в специальные теги "" .

Имя вашего хоста:

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-комментария:

-->

Скриптовые элементы

Спецификация JSP различает три типа скриптовых элементов:

  • Объявления
  • Выражения
  • Скриплеты

Объявления обычно используются для определения переменных, методов, внутренних классов и остальных действующих Java конструкций на уровне класса. В выражения вкладываются любые действующие выражения Java. С помощью скриплетов в JSP страницы вкладываются работающие части кода Java. Все эти элементы начинаются знаками . Обратите внимание и на то, что все скриптовые элементы отличаются немного записью конструкции. Объявления используют восклицательный знак (! ) в конструкции (), а выражения знак равенства (=) (), в то время как скриплеты используют стандартный формат записи ().

Объявления JSP

Объявления JSP позволят вам задавать переменные, методы, внутренние классы и так далее. Другими словами объявления Вы используете для определения конструкций Java, которые Вы в программе используете. Так как объявления не осуществляют вывода, то обычно они используются совместно с JSP выражениями или скриплетами. В приведённом в качестве примера фрагменте JSP отображается количество запросов к данной странице с момента загрузки сервера (или с момента последнего изменения и перезагрузки сервлета). Обратите внимание, что в примере мы используем как объявление, так и выражение и что внутри конструкции после объявления стоит точка с запятой (; ):

Количество обращений к странице с момента загрузки сервера:

Выражения JSP

Выражения JSP применяются для того, чтобы вставить значения Java непосредственно в вывод. Выражения Java вычисляются, конвертируются в строку и вставляются в страницу. Эти вычисления проходят во время выполнения (то есть при запросе страницы), а потому существует полный доступ к информации о самом запросе. В выражениях можно использовать постоянные, переменные, вызовы различных методов. Все выражения, вне зависимости от сложности их содержимого, вычисляются в один результат или число. JSP страницы полагаются на JSP Writer, который берёт любой результат выражения, переводит его в тип String (текстовый) и заносит в буферную память. Например, следующий код служит для отображения даты и времени запроса данной страницы:

Текущее время: Имя вашего хоста:

Необходимо обратить внимание на три правила:

  • JSP выражения должны в себе содержать выражения Java;
  • каждое JSP выражение должно содержать только одно выражение Java;
  • выражения JSP не должны заканчиваться точкой с запятой (;), в отличие от Jаva объявлений.
Скриплеты JSP

Если вы хотите сделать что-то большее чем просто вставку выражений, то скриплеты JSP дадут вам возможность вставить любой код в метод сервлета, который будет создан при обработке данной страницы. В данном случае Вы можете использовать большинство конструкций Java. Скриплеты также имеют доступ к тем же заранее определённым переменным, что и выражения. Поэтому, например, если вы хотите вывести что-нибудь на страницу, вы должны использовать заранее определённую переменную out .

Обратите внимание на то, что код внутри скриплета вставляется в том виде, как он был записан, и весь статический HTML (текст шаблона) до или после скриплета конвертируется при помощи оператора print . Например, следующий фрагмент JSP содержит смешанный текст шаблона и скриплета:

< B> Удачного< /B> вам дня! < B> Неудачного< /B> вам дня!

После преобразования скриплета код будет выглядеть следующим образом:

If (Math .random () < 0.5 ) { out.println ("Удачного вам дня!" ) ; } else { out.println ("Неудачного вам дня!" ) ; }

Это означает, что скриплеты не обязательно должны содержать завершённые фрагменты Java, и что оставленные открытыми блоки могут оказать влияние на статический HTML вне скриплета.

Директивы JSP

JSP страница может послать сообщение соответствующему контейнеру с указаниями какие действия необходимо провести. Эти сообщения называются директивами. Все директивы начинаются с . Директивы в JSP странице приводят к тому, что контейнер пошлёт заявку на исполнение определённой службы, которая в генерированном документе не объявляется. Форму записи директив можно изобразить следующим образом:

Вы также можете объединить установку нескольких атрибутов для одной директивы:

Существует три основных типа директив: page , которая позволяет вам совершать такие операции, как импорт классов, изменение суперкласса сервлета, и т. п.; include , которая даёт вам возможность вставить файл в класс сервлета при трансляции JSP файла в сервлет; и taglib , позволяющий расширить множество тегов своими собственными, которые JSP контейнер способен истолковать.

Директива JSP page

Как можно догадаться из названия, данная директива предоставляет атрибуты для JSP страницы. Атрибуты, определённые в этой директиве, внедряются в данную JSP страницу и на все её вложенные статические элементы, независимо от того были ли они вставлены с помощью директивы include или с помощью действия jsp:include . Форма записи директивы page следующая:

В качестве примера приведём следующую запись:

Эта директива заявляет, что JSP страница импортирует классы из двух пакетов Java, java.util и com.myclasses , а потом уточняет размер буферной памяти, которая должна быть использована для обработки данной JSP страницы.

  • import="пакет.class1, пакет.class2, ..., пакет.classN". Позволяет вам задать пакеты, которые должны быть импортированы. Это единственный атрибут, который может использоваться несколько раз в одной директиве. В список необходимо включить все классы Java, которые Вы хотите использовать и которые не являются частью исходного набора импортируемых классов. Исходный набор содержит: java.lang.*, javax.servlet.*, javax.servlet.jsp.* и javax.servlet.http.*. Пример использования атрибута import:

  • language="java". Данный атрибут предназначен для задания используемого языка программирования. По умолчанию принимается значение "java" . Этот атрибут необязательно использовать, но тем не менее проблема потом может наступить в случае, если поставщик JSP контейнера будет использовать другие языки (например, JavaScript). Пример записи данного атрибута следующий:

  • extends="пакет.class". Задаёт суперкласс (родительский класс) для генерируемого сервлета. Обычно сервлет возникает расширением исходного класса. Опытные программисты могут с помощью этого атрибута создавать собственные суперклассы. Пример использования этого атрибута может выглядеть следующим образом:

  • session="true|false". Данный атрибут может принимать значение true или false , которые определяют принимает ли участие JSP страница в трансляции HTTP . Значение true («истина», принимается по умолчанию) сигнализирует о том, что заранее определённая переменная session (тип HttpSession) должна быть привязана к существующей сессии, если таковая имеется, в противном случае создаётся новая сессия, к которой и осуществляется привязка. Значение false («ложь») определяет, что сессии не будут использоваться, и попытки обращения к переменной session приведут к возникновению ошибки при трансляции JSP страницы в сервлет. Пример использования данного атрибута может выглядеть следующим образом:

  • buffer="размерkb|none". Данный атрибут задаёт объём буферной памяти, необходимой для объекта JspWriter, на который ссылается заранее определённая переменная out . Значение принимаемое по умолчанию зависит от настроек сервера, но должно превышать 8kb . Значение задаётся либо в форме «размерkb» либо «none». Если Вы укажете значение буферной памяти как none , то сервлет не будет ничего сохранять в буферную память и передаст результат, записанный до переменной out , прямо объекту PrintWriter , который предоставляется вместе с объектом ServletResponse. Если Вы зададите значение буферной памяти на конкретную величину, то JspWriter будет в эту память сохранять данные, в результате чего увеличится производительность. В отличие от объекта PrintWriter объект JspWriter может вызывать исключительные ситуации IOExceptions . Исходная величина буферной памяти равна 8kB . Пример записи данного атрибута может выглядеть следующим образом:

  • autoflush="true|false". true или false . Значение true («истина», принимаемое по умолчанию) устанавливает, что при переполнении буферной памяти он автоматически очистится. Значение false («ложь»), которое крайне редко используется, устанавливает что переполнение буфера должно приводить к возникновению исключительной ситуации (IOExceptions). Обычно атрибуты buffer и autoflush устанавливаются вместе в одной директиве. При установке значение атрибута buffer="none" установка значения false для атрибута autoflush недопустима. Пример может выглядеть следующим образом:

  • isThreadSafe="true|false". Данный атрибут может принимать значения true или false . Значение true («истина», принимается по умолчанию) задаёт нормальный режим выполнения сервлета, когда множественные запросы обрабатываются одновременно с использованием одного экземпляра сервлета, исходя из соображения что автор синхронизировал доступ к переменным этого экземпляра. Значение false («ложь») сигнализирует о том, что сервлет должен наследовать SingleThreadModel (однопоточную модель), при которой последовательные или одновременные запросы обрабатываются отдельными экземплярами сервлета. Другими словами значение true приведёт к тому, что контейнер может посылать сервлету сразу несколько запросов, в то время как при значении false контейнер посылает запросы по одному. Пример использования выглядит так:

  • info="информация". Задаёт строку, которая может быть получена при использовании метода Servlet.getServletInfo(). Обычно этот метод возвращает информацию о сервлете (например, авторе, версии и авторских правах). Пример записи данного атрибута может выглядеть следующим образом:

  • errorPage="url". Задаёт JSP страницу, которая вызывается в случае возникновения каких-либо событий Throwables , которые не обрабатываются на данной странице. Случится ли на JSP странице исключение и JSP страница не имеет собственного кода для решения этого исключения, то контейнер автоматически передаст управление на URL , которую Вы задали в качестве значения атрибута errorPage . Пример записи выглядит так:

  • isErrorPage="true|false". Данный атрибут может принимать значения true или false . Сигнализирует о том, может ли эта страница использоваться для обработки ошибок для других JSP страниц или нет. По умолчанию принимается значение false («ложь»). Пример использования данного атрибута может выглядеть следующим образом:

  • contentType="MIME-Тип". Данный атрибут задаёт тип MIME для вывода и по желанию можно задать кодировку знаков в ответе (HTML ответе). По умолчанию в качестве значения MIME используется text/html . Для наглядности можем использовать следующий пример:

Того же результата можно добиться и использованием скриплета:

Директива JSP include

Эта директива позволяет Вам включать файлы в сервлет в процессе трансляции JSP страницы. Использование директивы выглядит следующим образом:

Заданный URL обычно интерпретируется относительно JSP страницы, на которой расположена ссылка, но, как и при использовании любых других относительных URL вы можете задать системе положение интересующего вас ресурса относительно домашнего каталога Web сервера, добавив в начало URL символ «/ ». Содержимое подключаемого файла обрабатывается как обычный текст JSP и поэтому может включать такие элементы как статический HTML , элементы скриптов, директивы и действия. Например, многие сайты используют небольшую панель навигации на каждой странице. В связи с проблемами использования фреймов HTML часто эта задача решается размещением небольшой таблицы сверху или в левой половине страницы, HTML код которой многократно повторяется для каждой страницы сайта. Директива include наиболее естественный способ решения этой задачи, избавляющий разработчика от кошмара рутины копирования HTML в каждый отдельный файл. Это происходит следующим образом:

< html> < head> < title> Тестовая страница< /title> < /head> < body> < /body> < /html>

Учтите что поскольку директива include подключает файлы в ходе трансляции страницы, то после внесения изменений в панель навигации вам потребуется повторная трансляция всех использующих её JSP страниц. Что в данном случае является хорошим компромиссом, поскольку как правило панель навигации меняется достаточно редко и процесс подключения не теряет своей эффективности. Если же подключённые файлы меняются довольно часто, вы можете использовать вместо этого действие jsp:include . Это действие подключает файл в процессе обращения к JSP.

Директива JSP taglib

Как уже известно, в JSP страницах элементы записываются с помощью знаков (условных знаков, меток, марок). Множество знаков, которые JSP контейнер способен истолковать, можно расширить с помощью так называемых библиотек знаков. Также к расширенному множеству знаков можно присоединять действия, вследствие чего происходит расширение самого языка JSP. Действия можно разделить на стандартные и собственные. Обобщённый способ записи может выглядеть так:

Библиотеку знаков необходимо идентифицировать с помощью URI адреса (уникального идентификатора ресурса). URI может быть как абсолютным так и отностительным. Уникальный идентификатор ресурса определяет расположение библиотеки знаков (TLD), который определяет собственные знаки этой библиотеки. Пример записи директивы:

JSP страница может содержать бесконечное кол-во директив taglib , но для каждой директивы необходимо установить различные префиксы, которые определяют содержимое библиотеки на странице. В качестве префикса можете использовать какой угодно текст, слово. В то время, как директиву taglib можно использовать где угодно на JSP странице, все собственные знаки, которые эти директивы используют, должны использоваться за ними.

Действия

Действия JSP используют конструкции с синтаксисом XML для управления работой движка сервлета. Вы можете динамически подключать файл, многократно использовать компоненты JavaBeans , направить пользователя на другую страницу или сгенерировать HTML для Java plugin. Все эти действия детально рассмотрены далее. Помните что как и во всем XML , имена элементов и атрибутов регистрозависимы. Действия можно разделить на две группы: стандартные и созданные (собственные, что создает сам программист). Допустимо применение следующих стандартных действий:

  • jsp:declaration - Объявление, аналогичен тегу ;
  • jsp:scriptlet - Скриптлет, аналогичен тегу ;
  • jsp:expression - Выражение, аналогичен тегу ;
  • jsp:text - Вывод текста;
  • jsp:useBean - Поиск или создание нового экземпляра JavaBean;
  • jsp:setProperty - Установка свойств JavaBean;
  • jsp:getProperty - Вставить свойство JavaBean в поток вывода;
  • jsp:include - Подключает файл в момент запроса страницы;
  • jsp:forward - Перенаправляет запрос на другую страницу;
  • jsp:param - Добавляет параметры в объект запроса, например в элементах forward, include, plugin.;
  • jsp:plugin - Генерирует код (в зависимости от типа используемого броузера), который создает тег OBJECT или EMBED для Java plugin;
  • jsp:params - Группирует параметры внутри тега jsp:plugin;
  • jsp:fallback - Указывает содержимое, которое будет использоваться браузером клиента, если подключаемый модуль не сможет запуститься. Используется внутри элемента plugin.
Действие jsp:useBean

Это действие позволяет загружать JavaBean для последующего использования на JSP странице. Эта возможность позволяет многократно использовать классы Java, не отказываясь при этом от преимуществ, предоставляемых сервлетами JSP. Помимо этого, это один из способов, как большую часть обработки Java исключить из JSP страницы. Если перенести обработку Java из JSP страницы до JavaBean, то потом эти функции можно использовать и в остальных JSP страницах. Простейший синтаксис для указания используемого bean:

< jsp:useBean id="имя" class ="пакет.class" />

Как правило это означает «создание нового экземпляра объекта класса, заданного через class , и его связь с переменной с именем, заданным при помощи id ». Однако можно задать атрибут scope (принимает значения page|request|session|application , page для страницы, request для запросов, session для сессий или диалогов, application для аппликаций), который ассоциирует bean не только с текущей страницей. В таком случае, полезно получить ссылки на существующие beans , и действие jsp:useBean создает экземпляр нового объекта лишь в том случае если не существует ни одного объекта с теми же значениями id и scope . Теперь, когда у вас есть bean , вы можете изменять его свойства при помощи действия jsp:setProperty , или используя для этого скриплет и явно вызывая метод объекта с именем переменной заданном ранее через атрибут id . Recall that with beans , когда вы говорите «у этого bean есть свойство типа X с названием foo », вы на самом деле имеете ввиду «у этого класса есть метод getFoo , который возвращает данные типа X, и другой метод setFoo , которому в качестве параметра передается X.» Действие jsp:setProperty более подробно рассмотрено в следующем разделе, но сейчас вы должны запомнить что вы можете либо явно задавать value , задавая атрибут param , чтобы получить значение из соответствующего параметра запроса, или просто перечислить свойства, чтобы получить значения из параметров запроса с теми же именами что и свойства. Вы можете получить значения существующих свойств при помощи выражений JSP или скриплетов, вызвав соответствующий метод getXxx , или (чаще всего), воспользовавшись действием jsp:getProperty .

Класс, заданный для bean, должен находиться в обычном каталоге классов сервера, а не в части, зарезервированной для классов, автоматически перезагружаемых после редактирования. Например, для Java Web Server, все используемые классы должны размещаться в каталоге classes или в .jar файле каталога lib , а не в каталоге servlets . Ниже приведен простой пример, загружающий bean и устанавливающий/получающий простой строковый параметр.

BeanTest.jsp

< html> < head> < title>< /title> < /head> < body> < h1> Многократное использование JavaBeans в JSP< /h1> < jsp:useBean id="test" class ="hall.SimpleBean" /> < jsp:setProperty name="test" property="message" value="Привет, WWW" /> < p> Сообщение: < jsp:getProperty name="test" property="message" /> < /p> < /body> < /html>

SimpleBean.java

Package hall ; public class SimpleBean { private String message = "Текст сообщения не задан" ; public String getMessage() { return (message) ; } public void setMessage(String message) { this .message = message; } }

Еще несколько деталей о использовании jsp:useBean . Простейший способ использовать bean - это использование конструкции:

< jsp:useBean id="имя" class ="пакет.class" />

для загрузки bean , а затем использовать jsp:setProperty и jsp:getProperty для модификации и получения его свойств (параметров). Однако существуют еще два других способа. Во-первых, вы можете использовать формат контейнера, а именно:

< jsp:useBean ...> Тело < /jsp:useBean>

для того чтобы обеспечить выполнение Тела только в том случае, если экземпляр bean создается впервые, а не тогда, когда находится и используется уже существующий bean . Как обсуждается далее, beans могут совместно использоваться, поэтому не каждое выражение jsp:useBean приводит к созданию экземпляра нового bean . Во-вторых, кроме id и class , существуют еще три других атрибута, которые вы можете использовать: scope , type , и beanName . Эти атрибуты описаны далее:

  • id - дает имя переменной, которая ссылается на bean . Если удается найти bean с теми же самыми значениями id и scope , то вместо создания нового экземпляра используется ранее созданный объект;
  • class - задает полное имя пакета bean ;
  • scope - задает область, в которой bean должен быть доступен. Может принимать четыре допустимых значения: page , request , session и application . По умолчанию принимает значение page , означающее что bean доступен только на текущей странице (размещается в PageContext текущей страницы). Значение request означает что bean доступен только для текущего запроса клиента (размещается в объекте ServletRequest). Значение session означает что объект доступен всем страницам на протяжении жизни текущей HttpSession . И, наконец, значение application означает что он доступен всем страницам, использующим тот же самый ServletContext . Причина необходимости этого атрибута заключается в том что jsp:useBean приводит к созданию нового экземпляра объекта в том случае, если нет уже существующего объекта с тем же id и scope . Иначе используется уже существующий объект, и все элементы jsp:setParameter или любые другие между тегами jsp:useBean игнорируются.
  • type - указывает тип переменной, которая ссылается на объект. Должен совпадать с именем класса, суперкласса или реализуемого интерфейса. Запомните что имя переменной задается через атрибут id .
  • beanName - дает имя bean , которое будет использовано методом instantiate . Можно задать type и beanName , и опустить атрибут class .
Действие jsp:setProperty

Вы можете использовать jsp:setProperty для присвоения значений свойствам ранее описанных beans . Вы можете делать это двумя способами. Во-первых, вы можете использовать jsp:setProperty после, но вне элемента jsp:useBean , так как это показано в примере:

< jsp:useBean id="myName" ... /> ... < jsp:setProperty name="myName" property="someProperty" ... />

В этом случае jsp:setProperty выполняется независимо от того, был ли найден существующий bean или был создан новый экземпляр. Другим вариантом заключается в размещении jsp:setProperty в теле элемента jsp:useBean , как это показано в другом примере:

< jsp:useBean id="myName" ... > ... < jsp:setProperty name="myName" property="someProperty" ... /> < /jsp:useBean>

При этом jsp:setProperty выполняется лишь в том случае, если был создан новый экземпляр объекта, а не тогда, когда находится уже существующий. Действие jsp:setProperty допускает применение следующих четырех атрибутов:

  • name - этот обязательный атрибут служит для задания bean , свойства которого будут устанавливаться. Элемент jsp:useBean должен предшествовать использованию элемента jsp:setProperty .
  • property - этот обязательный атрибут устанавливает свойство, которое вы хотите установить. Однако существует частный случай: значение «* » означает что все параметры запроса, чьи имена совпадают с именами свойств bean будут переданы соответствующему методу установки свойств.
  • value - этот необязательный атрибут устанавливает значение свойства. Строковые значения автоматически преобразуются в числовые, boolean , Boolean , byte , Byte , char и Character с использованием стандартного метода valueOf соответствующего класса. Например, значение "true" для свойства boolean или Boolean будет конвертированно при помощи метода Boolean.valueOf , а значение «42» для свойства int или Integer будет конвертированно при помощи метода Integer.valueOf . Вы не можете одновременно использовать атрибуты value и param , но можете вообще их не использовать. Ознакомьтесь с описанием атрибута param , которое представлено ниже.
  • param - этот необязательный атрибут устанавливает параметр запроса, используемый для получения свойства. Если в текущем запросе этот параметр отсутствует, никаких действий не происходит: система не передает значение null методу устанавливающему свойства. Таким образом, допустимо использование в bean свойств по умолчанию, переопределяя их лишь в том случае если этого требуют параметры запроса. Например, следующий фрагмент означает следующее: «установить свойство numberOfItems в соответствии со значением параметра запроса numItems , а если такой параметр в запросе отсутствует - никакие действия не выполняются.»

< jsp:setProperty name="orderBean" property="numberOfItems" param="numItems" />

Если вы не используете ни value , ни param , это приравнивается к тому, как если бы вы задали имя param совпадающее с именем property . Вы можете применить этот принцип автоматического использования свойств запроса, чьи имена совпадают с именами свойств и пойти далее, задав в качестве имени свойства «* » и опустив параметры value и param . В этом случае сервер обработает допустимые свойства и параметры запроса, на предмет совпадения их с идентичными именами. Далее приведен пример в котором используется bean для создания таблицы простых чисел. Если существует параметр numDigits в данных запроса, он передается в свойство bean numDigits . Аналогично для numPrimes . JspPrimes.jsp

< html> < head> < title> Многократное использование JavaBeans в JSP< /title> < /head> < body> < h1> Многократное использование JavaBeans в JSP< /h1> < jsp:useBean id="primeTable" class ="hall.NumberedPrimes" /> < jsp:setProperty name="primeTable" property="numDigits" /> < jsp:setProperty name="primeTable" property="numPrimes" /> < p> Несколько < jsp:getProperty name="primeTable" property="numDigits" /> символьных простых чисел: < jsp:getProperty name="primeTable" property="numberedList" /> < /p> < /body> < /html>

Действие jsp:getProperty

Этот элемент определяет значение свойства bean , конвертирует его в строку и направляет в поток вывода. Для выполнения действия требуется задание двух атрибутов: имени bean , которое предварительно задается в действии jsp:useBean , и имя свойства, значение которого должно быть определено. Далее приведен пример использования этого действия:

< jsp:useBean id="itemBean" ... /> ... < UL> < LI> Количество предметов: < jsp:getProperty name="itemBean" property="numItems" /> < LI> Цена за штуку: < jsp:getProperty name="itemBean" property="unitCost" /> < /UL>

Действие jsp:include

Это действие позволяет вставлять содержимое файлов в генерируемую страницу. Синтаксис действия:

< jsp:include page="относительный URL" flush="true" />

В отличие от директивы include , которая вставляет файл на этапе трансляции JSP страницы, это действие вставляет файл при запросе страницы. Это приводит к некоторой потере эффективности и исключает возможность наличия во вставляемом файле кода JSP, но зато дает существенное преимущество в гибкости.

Пример вставки содержимого четырех файлов в JSP-страницу:

< html> < head> < title> Новости< /title> < /head> < body> < h1> Новости< /h1> < p> Вот фрагменты наших четырех самых популярных статей:< /p> < ol> < li>< jsp:include page="news/Item1.html" flush="true" />< /li> < li>< jsp:include page="news/Item2.html" flush="true" />< /li> < li>< jsp:include page="news/Item3.html" flush="true" />< /li> < li>< jsp:include page="news/Item4.html" flush="true" />< /li> < /ol> < /body> < /html>

Действие jsp:forward

Это действие позволяет вам передать запрос другой статической HTML странице, сервлету или JSP странице. В отличие от действия jsp:include обработка актуальной страницы заканчивается. Оно использует один атрибут page , который должен содержать относительный URL и на основании которого упорядочен объект request . К исходным параметрам запроса, которой передается другой странице, можете с помощью действия jsp:param добавить и другие параметры. Значением атрибута page может быть как статическое значение, так и вычисляемое в процессе запроса, что и показано на следующих двух примерах:

< jsp:forward page="/utils/errorReporter.jsp" /> < jsp:forward page="" />

Также с помощью действия jsp:forward можно передать управление на другую страницу, но с условием, что перед вызовом этого действия ничего не было записано в выходящую буферную память (иначе будет вызвано исключение IllegalStateException).

Действие jsp:param и действие jsp:params

Это действие предоставляет информацию типа название/значение. Данное действие используется в основном вместе со знакомыми уже действиями jsp:include и jsp:forward . Кроме этого его можно использовать и вместе с действием jsp:plugin . В остальных случаях использование этого действия не имеет значения. Использование jsp:param с действиями jsp:include и jsp:forward передаться новым страницам исходный объект request , который будет расширен на новые параметры. Если Вы зададите новые значения для уже существующих параметров, то именно новые значения будут иметь преимущество. С помощью действия jsp:params можно задать сразу несколько параметров

Действие jsp:plugin

Это действие позволяет вам вставить элемент OBJECT или EMBED (в зависимости от типа используемого браузера), необходимый для запуска аплетов, использующих plugin Java. Другими словами данное действие служит к генерированию HTML для вложения Java API в JSP страницу. Таким же образом можете вставлять URL для скачивания модулей для Java API от JavaSoft, который предоставляет возможность запускать аплеты внутри браузера. Форма записи данного действия выглядит следующим образом.

30 ответов

Использование скриптлетов (эти %% вещи) в действительно крайне не рекомендуется с момента рождения taglibs (например, ) и ( , эти ${} вещи) еще в 2001 году.

Основными недостатками скриплетов являются:

  • Возможность повторного использования : вы не можете повторно использовать скриптлеты.
  • Заменимость: вы не можете сделать скриптлеты абстрактными.
  • ОО-способность: вы не можете использовать наследование/композицию.
  • Отладка: если скриптлет выбрасывает исключение на полпути, вы получаете только пустую страницу.
  • Тестируемость: скриптлеты не тестируются юнитами.
  • Ремонтопригодность: для сохранения логики смешанного/загроможденного/дублированного кода требуется больше времени.
  • Сам Sun Oracle также рекомендует в соглашениях по кодированию JSP избегать использования скриптлетов, когда те же функции возможны с помощью (тегов) классов. Вот несколько ссылок:

    Из спецификации JSP 1.2 настоятельно рекомендуется использовать в вашем веб-приложении стандартную библиотеку тегов JSP (JSTL), чтобы уменьшить потребность в скриплетах JSP на ваших страницах. Страницы, использующие JSTL, в общем, легче читать и поддерживать.

    По возможности избегайте JSP-скриптлетов, когда библиотеки тегов предоставляют эквивалентную функциональность. Это облегчает чтение и обслуживание страниц, помогает отделить бизнес-логику от логики представления и облегчает превращение ваших страниц в страницы в стиле JSP 2.0 (спецификация JSP 2.0 поддерживает, но не подчеркивает использование скриптлетов).

    В духе принятия шаблона проектирования модель-представление-контроллер (MVC) для уменьшения связи между уровнем представления и бизнес-логикой сценарии JSP не должны использоваться для написания бизнес-логики. Вместо этого JSP-скриптлеты используются при необходимости для преобразования данных (также называемых "объектами значений"), возвращаемых при обработке клиентских запросов, в надлежащий формат, готовый для клиента. Даже тогда это лучше сделать с помощью сервлета фронт-контроллера или пользовательского тега.

    То, как заменить скриптлеты, полностью зависит от единственной цели кода/логики. Чаще всего этот код помещается в полноценный класс Java:

      Если вы хотите вызывать один и тот же код Java при каждом запросе, в меньшей или большей степени независимо от запрашиваемой страницы, например, проверяя, вошел ли пользователь в систему, тогда реализуйте и соответственно пишите код в doFilter() . Например:

      Public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { if (((HttpServletRequest) request).getSession().getAttribute("user") == null) { ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page. } else { chain.doFilter(request, response); // Logged in, just continue request. } }

      При отображении на соответствующий охватывающий интересующие JSP-страницы, вам не нужно копировать и вставлять один и тот же фрагмент кода в общие JSP-страницы.

      предварительной обработки запроса, например, предварительно загрузить некоторый список из базы данных для отображения в некоторой таблице, при необходимости, основываясь на некоторых параметрах запроса, то реализуйте и напишите код соответствующим образом в методе doGet() . Например:

      Protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { ListProducts = productService.list(); // Obtain all products. request.setAttribute("products", products); // Store products in request scope. request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table. } catch (SQLException e) { throw new ServletException("Retrieving products failed!", e); } }

      Таким образом, иметь дело с исключениями проще. К БД не обращаются во время рендеринга JSP, но задолго до того, как JSP был отображен. У вас все еще есть возможность изменить ответ всякий раз, когда доступ к БД вызывает исключение. В приведенном выше примере будет отображена страница ошибки 500 по умолчанию, которую вы в любом случае можете настроить с помощью в web.xml .

      Если вы хотите вызвать некоторый Java-код для постобработки запроса, например, обработки отправки формы, то реализуйте и напишите код соответствующим образом в методе doPost() . Например:

      Protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); User user = userService.find(username, password); if (user != null) { request.getSession().setAttribute("user", user); // Login user. response.sendRedirect("home"); // Redirect to home page. } else { request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope. request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error. } }

      Это облегчает работу с различными адресами на странице результатов: повторное отображение формы с ошибками проверки в случае ошибки (в данном конкретном примере вы можете повторно отобразить ее, используя ${message} в ), или просто переход на нужную целевую страницу в случае успеха.

      Если вы хотите вызвать некоторый Java-код для управления планом выполнения и/или местом назначения запроса и ответа, то реализуйте соответствии с шаблоном фронт-контроллера MVC . Например:

      Protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Action action = ActionFactory.getAction(request); String view = action.execute(request, response); if (view.equals(request.getPathInfo().substring(1)) { request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response); } else { response.sendRedirect(view); } } catch (Exception e) { throw new ServletException("Executing action failed.", e); } }

      Или просто используйте MVC-инфраструктуру, такую как , и т.д., Чтобы в итоге вы получили только страницу JSP/Facelets и класс JavaBean без необходимости использования собственного сервлета.

      Если вы хотите вызвать некоторый Java-код для управления потоком внутри JSP-страницы, то вам нужно получить (существующий) taglib управления потоком, такой как ядро JSTL . Например, отображение ListВ таблице:

      ...

      ${product.name} ${product.description} ${product.price}

      С тегами в стиле XML, которые хорошо вписываются в этот HTML, код лучше читается (и, следовательно, лучше поддерживается), чем набор скриплетов с различными открывающими и закрывающими скобками ("Куда, черт возьми, относится эта закрывающая скобка?"). Легкая помощь состоит в том, чтобы настроить ваше веб-приложение на выдачу исключения, когда скриптлеты все еще используются, добавив следующий фрагмент в web.xml:

      *.jsp true ...

      Обратите внимание, что чувствительность XSS никоим образом не связана конкретно с Java/JSP/JSTL/EL/чем бы то ни было, эту проблему необходимо учитывать в каждом разрабатываемом веб-приложении. Проблема скриплетов в том, что они не предоставляют встроенных предупреждений, по крайней мере, не используя стандартный Java API. У преемника JSP Facelets уже есть неявное экранирование HTML, поэтому вам не нужно беспокоиться о дырах XSS в Facelets.

      Как защитник: отключить скрипты для хорошего

      Вы можете использовать теги JSTL вместе с выражениями EL, чтобы избежать смешения Java и HTML-кода:

      // and so on

      Существуют также основанные на компонентах фреймворки, такие как Wicket , которые генерируют много HTML для вас. Теги, которые попадают в HTML, являются чрезвычайно базовыми, и в них практически нет логики, в результате чего возникают почти пустые страницы HTML с типичными элементами HTML. Недостатком является то, что в API Wicket есть много компонентов, и некоторые из них могут быть трудными для достижения этих ограничений.

      В архитектурном шаблоне MVC JSP представляют собой слой "Вид". Встраивание java-кода в JSP считается плохой практикой. Вы можете использовать JSTL , velocity с JSP как "механизм шаблонов". Поставщик данных для этих тегов зависит от фреймворков , с которыми вы имеете дело. Struts 2 и webwork в качестве реализации шаблона MVC использует OGNL "очень интересный метод для раскрытия Beans Свойства для JSP".

      Опыт показал, что JSP имеет некоторые недостатки, один из которых трудно избежать смешивания разметки с фактическим кодом.

      Если вы можете, подумайте об использовании специализированной технологии для того, что вам нужно сделать. В Java EE 6 есть JSF 2.0, который обеспечивает множество приятных функций, включая склеивание Java beans вместе с страницами JSF с помощью подхода #{bean.method(argument)} .

      Если вы просто хотите избежать недостатков Java-кодирования в JSP, вы можете сделать это даже с помощью скриптов. Просто следуйте некоторой дисциплине, чтобы иметь минимальную Java в JSP и почти нет вычислений и логики на странице JSP.

      // and so on

      Научитесь настраивать и писать свои собственные теги с помощью JSTL

      Обратите внимание, что EL является EviL (исключения времени выполнения, рефакторинг)
      Калитка также может быть злой (производительность, трудная для небольших приложений или простой уровень обзора)

      Пример из java2s,

      Это необходимо добавить в веб-приложение web.xml

      /java2s /WEB-INF/java2s.tld

      создать файл: java2s.tld в /WEB -INF/

      1.0 1.2 Java2s Simple Tags bodyContentTag com.java2s.BodyContentTag JSP howMany

      скомпилируйте следующий код в WEB-INF\classes\com\java2s

      Package com.java2s; import java.io.IOException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTagSupport; public class BodyContentTag extends BodyTagSupport{ private int iterations, howMany; public void setHowMany(int i){ this.howMany = i; } public void setBodyContent(BodyContent bc){ super.setBodyContent(bc); System.out.println("BodyContent = "" + bc.getString() + """); } public int doAfterBody(){ try{ BodyContent bodyContent = super.getBodyContent(); String bodyString = bodyContent.getString(); JspWriter out = bodyContent.getEnclosingWriter(); if (iterations % 2 == 0) out.print(bodyString.toLowerCase()); else out.print(bodyString.toUpperCase()); iterations++; bodyContent.clear(); // empty buffer for next evaluation } catch (IOException e) { System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage()); e.printStackTrace(); } // end of catch int retValue = SKIP_BODY; if (iterations < howMany) retValue = EVAL_BODY_AGAIN; return retValue; } }

      Запустите сервер и загрузите bodyContent.jsp в браузере

      A custom tag: body content This page uses a custom tag manipulates its body content.Here is its output:

    • java2s.com
    • Вы подняли хороший вопрос, и хотя у вас есть хорошие ответы, я бы посоветовал вам избавиться от JSP. Это устаревшая технология, которая в конечном итоге умрет. Используйте современный подход, например, движки шаблонов. У вас будет очень четкое разделение слоев бизнеса и презентаций и, конечно же, кода Java в шаблонах, поэтому вы можете создавать шаблоны непосредственно из программного обеспечения для редактирования веб-презентаций, в большинстве случаев использующих WYSIWYG.

      И, конечно, избегайте фильтров и предварительной и последующей обработки, иначе вы можете столкнуться с проблемами поддержки/отладки, поскольку вы всегда не знаете, где переменная получает значение.

      Независимо от того, насколько вы стараетесь избегать, когда вы работаете с другими разработчиками, некоторые из них по-прежнему предпочитают скриптлет, а затем вставляют злой код в проект. Поэтому настройка проекта при первом знаке очень важна, если вы действительно хотите уменьшить код сценария. Существует несколько способов преодолеть это (в том числе несколько фреймворков, о которых упоминалось выше). Однако, если вы предпочитаете чистый JSP-путь, используйте файл тегов JSTL. Самое приятное в этом - вы также можете настроить мастер-страницы для своего проекта, чтобы другие страницы могли наследовать мастер-страницы

      Создайте главную страницу под названием base.tag под вашими WEB-INF/тегами со следующим контентом

      .... .....

      На этой странице mater я создал фрагмент под названием "title", так что на дочерней странице я мог вставить больше кодов в это место главной страницы. Кроме того, тег будет заменен содержимым дочерней страницы

      Создать дочернюю страницу (child.jsp) в папке WebContent:

      используется для указания главной страницы, которую вы хотите использовать (в данный момент это base.tag). Все содержимое внутри тега здесь заменит на главной странице. Ваша дочерняя страница также может содержать любые теги lib, и вы можете использовать ее, как и другие. Однако, если вы используете код сценария здесь ( ...) и попробуйте запустить эту страницу, вы получите JasperException because Scripting elements (