Введение в jsp


Содержание
  • Введение в JavaServer Faces 1.2: Часть 1. Создание простых приложений
  • JSF для начинающих
  • Совершенствование Калькулятора
  • Добавление контроллера
  • Навигация в JSF
  • Заключение
  • Вопросы и ответы на собеседование по теме Java Server Pages (JSP)
  • Вопросы
  • Ответы
  • 1. Что такое jsp и зачем он нужен?
  • 2. Расскажите об этапах (фазах) жизненного цикла jsp.
  • 3. Расскажите о методах жизненного цикла jsp.
  • 4. Какие методы жизненного цикла JSP могут быть переопределены?
  • Две модели JSP
  • Предисловие
  • Обзор технологии Java Server Pages
  • Архитектура JSP-страницы
  • Основные модели архитектуры JSP
  • Первая модель архитектуры JSP
  • Вторая модель архитектуры JSP
  • Функционирование JSP
  • Жизненный цикл страницы JSP
  • Трансляция и компиляция
  • Выполнение
  • Синтаксис JSP-страницы
  • Директивы JSP
  • Директива page
  • Директива taglib
  • Директива include
  • Объявления JSP
  • Скриптлеты JSP
  • Выражения JSP
  • Комментарии JSP
  • Действия JSP-страницы
  • Атрибуты тега действия
  • Действие
  • Действие
  • Действие
  • Действие
  • Действие
  • Действие
  • Действие
  • Действие
  • Неявные объекты
  • Компонент JavaBean
  • Теги JSP
  • Интерфейс Tag
  • Интерфейс IterationTag
  • Интерфейс BodyTag
  • Использование тегов с атрибутами
  • Пример JSP-страницы
  • Перевод руководства по JavaServer Pages JSP 1.2
  • Версия: 1.2
  • ЛИЦЕНЗИЯ
  • ТОРГОВЫЕ МАРКИ
  • ОГРАНИЧЕННАЯ ГАРАНТИЯ
  • ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ
  • ОГРАНИЧЕННЫЕ ПРАВА
  • КУДА СООБЩИТЬ
  • Статус
  • JSP.S.1 Процессы Сообщества Java
  • JSP.S.2 JCP и Эта Спецификация
  • Предисловие
  • JSP.P.1 Сравнение с JSP 1.1
  • JSP.P.2 Лицензирование Спецификации
  • JSP.P.3 Для кого предназначен этот документ
  • JSP.P.4 Родственные Документы
  • В чем разница между JSF, Servlet и JSP? Введение в сетевое программирование
  • Неявные объекты
  • JSP директивы
  • Скриптовые элементы JSP
  • Эта страница была загружена
  • Hello, world! It»s
  • Here»s an object:
  • This page has been up seconds
  • Page has been accessed times since
  • Извлечение полей и значений
  • Введение в JSP.
  • Entity
  • Второй способ: пишем над геттерами. Пояснения смотрим в коде.
  • Теперь приведем пример нашего HibernateUtil
  • Категории
  • Сохранить в БД
  • [И тут какие-то данные]
  • Компоненты Java Server Pages. Введение в JSP. Типичные области использования JSP. Архитектуры модели 1 и модели 2

    Страницы работы

    Содержание работы

    Глава 11Компоненты JavaServerPages

    Соответствие процессу: эта глава посвящена проектированию в рамках дисциплины анализа и проектирования рационального унифицированного процесса (RUP). Также здесь рассматриваются аспекты реализации в контексте технологии JSP.

    Еще несколько лет назад термин тонкий клиент никому не был известен. Все изменилось с приходом Web-броузеров и возникшей после этого модой на создание сложных Web-приложений практически в каждой отрасли.

    Как известно, в тонких клиентах для представления данных используется язык разметки. Поэтому сложные серверные приложения, написанные на языках наподобие Java, генерируют документы на этом языке.

    Такое смешение программных аспектов приложения с аспектами представления данных имеет следующие отрицательные стороны.

    · Представление подвержено частым изменениям. Это приводит к большому объему повторного компилирования и сборки из-за обстоятельств, которые не имеют ничего общего с логикой приложения.

    · Представление данных должно быть закодировано средствами языка программирования с помощью, например, таких конструкций, как println. Это означает, что структура представления будет не такой понятной, как если бы данные выводились в самой программе, и это представление нельзя будет увидеть до запуска приложения. С точки зрения разработчика сервлетов, так же трудно читать строку за строкой код HTML, заключенный в операторы println.

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

    Технология JavaServerPages (JSP) была разработана специально для решения этих проблем.

    Подобно сервлетам, JSP представляет собой разновидность Web-компонентов платформы Java 2 Enterprise Edition (J2EE). Технология JSP напоминает технологию скриптов на стороне сервера, но имеется существенное различие: компоненты JSP компилируются, а скрипты интерпретируются. JSP позволяет внедрять программные элементы в документы HTML, которые затем обрабатываются Web-броузером. Для обработки на стороне сервера в JSP используется технология сервлетов Java.

    Компонент JSP состоит из кода Java, внедренного в структурированный документ, такой как HTML или XML. Главная идея JSP заключается в том, чтобы использовать язык разметки для статичных частей представления и внедрять на страницу специальные теги для реализации динамического содержимого. Теги также служат для обработки поступающих от клиента запросов и генерирования ответов. Когда к JSP поступает запрос, код JSP обрабатывается на сервере, и результаты обработки вместе со статичными частями HTML передаются клиенту.

    Технология JSP позволяет легко обслуживать код представления как обычный код HTML и ограждает разработчика Сети от необходимости иметь дело с незнакомым языком и инструментальными средствами.

    Можно возразить, что код Java все равно внедрен в JSP, и поэтому представление и логика приложения на самом деле не разделяются. Однако попробуем взглянуть с точки зрения разработчика. В сервлетах с представлением неминуемо приходится работать в рамках программирования, тогда как компоненты JSP ориентированы прежде всего на представление, а программные части для управления динамическими аспектами только внедряются в это представление.

    Типичные области использования JSP

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

    Наиболее эффективным будет сочетание этих двух технологий. Целесообразно применять JSP для задач представления данных и использовать сервлеты там, где на первое место выходит логика. Компоненты JSP идеально подходят для тех ситуаций, где требуется выдавать клиенту динамическое содержимое. Вообще, компоненты JSP должны заниматься прежде всего представлением, и любой код Java в составе JSP должен служить в первую очередь для связи с сервлетами и/или другими объектами управления или объектами данных.

    Компоненты JSP потребляют дополнительные системные ресурсы (например, требуют компилирования), поэтому их не следует применять там, где содержимое представления статично. В таких случаях достаточно простой страницы HTML.

    Архитектуры модели 1 и модели 2

    В начале истории JSP среди разработчиков были особенно популярны две архитектуры, обычно называемые модель 1 и модель 2. Сейчас в большинстве проектов применяется модель 2, однако еще можно найти некоторые простые ситуации, где модель 1 имеет свои преимущества.

    Thinking In Java Enterprise (русский перевод) → JavaServer Pages

    JavaServer Pages (JSP) — это стандартное расширение Java, которое определено поверх сервлетных расширений. Цель JSP состоит в упрощении создания и управления динамическими Web страницами.

    Как упоминалось ранее, свободно распространяемый Tomcat, реализация от jakarta.apache.org, автоматически поддерживает JSP.

    JSP позволяет вам комбинировать HTML Web страницы с кусочками кода Java в одном документе. Java код обрамляется специальными тегами, которые говорят JSP контейнеру, что он должен использовать код для генерации единого документа или его части. Выгода JSP состоит втом, что вы можете содержать единый документ, которые представляет и страницу, и Java код, который в нее включен. Недостаток состоит в том, что тот, кто поддерживает работоспособность JSP страницы, должен иметь опыт и HTML, и в Java (однако, со временем ожидается появление визуальных построителей JSP страницы).

    При первой загрузке JSP загружается JSP контейнером (который обычно ассоциирован, или является частью Web сервера), далее сервлетный код, который обязательно выделяется JSP тегами, автоматически генерируется, компилируется и загружается в контейнер сервлетов. Статическая часть HTML страницы производится посредством посылки статического объекта типа String в метод write( ). Динамическая часть включается прямо в сервлет.

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

    Структура JSP страницы — это что-то среднее между сервлетом и HTML страницей. JSP тэги начинаются и заканчиваются угловой скобкой, также как и HTML коды, но теги также включают знаки процента, так что все JSP теги обозначаются так:

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

    Вот чрезвычайно простой JSP пример, который использует стандартный библиотечный Java вызов для получения текущего времени в миллисекундах, которое затем делится на 1000, чтобы получить время в секундах. Так как используется JSP выражение ( @ directive < attr = "value" >* %>

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

    сообщает, что скриптовой язык, используемый внутри JSP страницы, это Java. Фактически, JSP спецификация только описывает семантику скриптов для языковых атрибутов, эквивалентных «Java». Смысл этой директивы состоит во встраивании гибкости в JSP технологию. В будущем, если вы выберите другой язык, скажем Python (хороший выбор для скриптов), то такой язык должен иметь поддержку Java Run-time Environment, выставляя наружу объектную модель Java технологии для скриптового окружения, особенно для неявных переменных, определенных выше, свойств JavaBeans и публичных методов.

    Наиболее важными директивами являются директивы страницы. Они определяют несколько атрибутов страницы и взаимодействие этих атрибутов с JSP контейнером. Эти атрибуты включают: language, extends, import, session, buffer, autoFlush, isThreadSafe, info и errorPage. Например:

    Эта строка, прежде всего, указывает, что эта страница требует участие в HTTP сессии. Так как мы не установили директиву языка, JSP контейнер по умолчанию использует Java и неявную переменную скриптового языка с названием session типа javax.servlet.http.HttpSession. Если бы директива использовала false, то неявная переменная session будет недоступна. Если переменная session не определена, то по умолчанию считается «true».

    Атрибут import описывает типы, которые доступны для скриптовой среды. Этот атрибут используется так же, как и в языке программирования Java, т. е., разделенный запятыми обычный список выражений import. Этот список импортируется транслируемой реализацией JSP страницы и доступен для скриптового окружения. Скажем еще раз, что в настоящее время это определено, только если значением директивы языка является «java».

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

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

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

    Кроме тоге, есть два типа комментариев:

    Первая форма позволяет вам добавлять комментарии в исходный код JSP, которые ни в какой форме не появятся в HTML странице, посылаемой клиенту. Конечно, вторая форма комментариев не специфична для JSP — это обычный HTML комментарий. Интересно то, что вы можете вставлять JSP код внутрь HTML комментария и результат будет показан в результирующей странице.

    Декларации используются для объявления переменных и методов в скриптовом языке (в настоящее время только в Java), используемых на JSP странице. Декларация должна быть законченным Java выражением и не может производить никакого вывода в выходной поток. В приведенном ниже примере Hello.jsp декларации для переменных loadTime, loadDate и hitCount являются законченными Java выражениями, которые объявляют и инициализируют новые переменные.

    Когда вы запустите эту программу, вы увидите, что переменные loadTime, loadDate и hitCount содержат свои значения между обращениями к странице, так что они явно являются полями, а не локальными переменными.

    В конце примера помещен скриплет, который пишет «Goodbye» на консоль Web сервера и «Cheerio» в неявный объект вывода JspWriter. Скриплет может содержать любые фрагменты кода, которые являются имеющими силу инструкциями Java. Скриплеты выполняются во время обработки запроса. Когда все фрагменты скриплета в данном JSP будут скомбинированы по порядку своего появления в JSP странице, они должны дать имеющую силу инструкцию, определенную для языка программирования Java. Будет ли скриплет производить вывод в выходной поток или нет, зависит только от кода скриплета. Вы должны знать, что скриплет может воздействовать на объекты, которые видимы для него.

    JSP выражения можно найти вперемешку с HTML в среднем разделе Hello.jsp. Выражения должны быть законченными Java инструкциями, которые вычисляются, переводятся в строку и посылаются в вывод. Если результат инструкции не может быть переведен в строку (String), будет выброшено исключение ClassCastException.

    Извлечение полей и значений

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

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

    Атрибуты JSP страницы и область видимости

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

    Этот пример также показывает использование встроенного HTML и записи в out, чтобы в результате получить HTML страницу.

    Первая часть информации производит имя сервлета, которое, вероятнее всего, будет просто «JSP», но это зависит от вашей реализации. Вы можете также определить текущую версию контейнера сервлетов, используя объект application. И, наконец, после установки атрибута сессии в обычной области видимости отображаются «имена атрибутов». Обычно вы не используете область видимости в большинстве JSP; они показаны здесь просто, чтобы добавить интереса в этот пример. Есть три следующие атрибута области видимости: область видимости страницы (scope 1), область видимости запроса (scope 2), область видимости сессии (scope 3 — здесь доступен только один элемент — это «My dog», добавленный прямо перед циклом) и область видимости приложения (scope 4), основанная на объекте ServletContext. Есть один ServletContext на каждое «Web приложение» в каждой Java Машине. («Web приложение» — это набор сервлетов и содержимого, установленного под определенным подмножеством URL’ов Сервера, таких как /catalog. Они устанавливаются с помощью конфигурационного файла.) В области видимости приложения вы увидите объекты, которые представляют пути для рабочего каталога и временного каталога.

    Манипуляция сессиями в JSP

    Сессии были введены в предыдущем разделе, посвященном сервлетам и также доступны в JSP. Следующие примеры исследуют сессионные объекты и позволяют вам манипулировать промежутком времени, прежде, чем сессия станет недействительной.

    Объект сессии предоставляется по умолчанию, так что он доступен без дополнительного кода. Вызов getID( ), getCreationTime( ) и getMaxInactiveInterval( ) используются для отображения информации об этом сессионном объекте.

    Когда вы в первый раз получите эту сессию, вы увидите, что MaxInactiveInterval составляет, например, 1800 секунд (30 минут). Это зависит от конфигурации вашего контейнера JSP/сервлетов. MaxInactiveInterval сокращается до 5 секунд, чтобы сделать вещи интереснее. Если вы перегрузите страницу до того, как истекут 5 секунд, то вы увидите:

    Но если вы подождете больший интервал, то «Ralph» станет null.

    Чтобы посмотреть, как сессионная информация переносится на другие страницы, а также, чтобы посмотреть эффект становления объекта сессии недействительным по сравнению с простым вариантом, когда вы дали ему устареть, созданы две новые страницы. Первая (доступна при нажатии кнопки «invalidate» в SessionObject.jsp) читает сессионную информацию, а затем явно делает сессию недействительной:

    Чтобы экспериментировать с этим, обновите SessionObject.jsp, затем сразу же кликните на кнопку «invalidate», чтобы перейти к странице SessionObject2.jsp. В этом месте вы все еще будете видеть «Ralph» и сразу после этого (прежде, чем пойдет интервал в 5 секунд), обновите SessionObject2.jsp, чтобы увидеть, что сессия была успешно сделана недействительной и «Ralph» исчез.

    Если вы вернетесь на SessionObject.jsp, обновите страницу так, чтобы вы снова имели 5-ти секундный интервал, затем нажмете кнопку «Keep Around», то вы попадете на следующую страницу SessionObject3.jsp, которая не делает сессию недействительной:

    Поскольку эта страница не делает сессию недействительной, «Ralph» будет оставаться во время каждого обновления страницы до тех пор, пока не пройдет 5-ти секундный интервал между обновлениями. Это мало чем отличается от игрушки «Tomagotchi» — до тех пор, пока вы играете с «Ralph», он будет здесь, в противном случае он исчезнет.

    Создание и изменение cookies

    Cookie были введены в предыдущем разделе о сервлетах. Опять таки, краткость JSP делает обращение с cookies более простым, чем при использовании сервлетов. Следующий пример показывает это с помощью получения cookie, которые пришли в запросе, чтения и изменения максимального возраста (дата устаревания) и присоединения нового cookie в ответный запрос:

    Так как каждый браузер хранит cookie по-своему, вы можете видеть разное поведение в разных браузерах (не убежден, но это может быть некоторой ошибкой, которая может быть исправлена в то время, когда вы читаете это). Также вы можете получить разные результаты, если вы выгрузите браузер и запустите его, по сравнению с тем, если вы посетите другую страницу, а затем вернетесь на Cookies.jsp. Обратите внимание, что использование объекта сессии выглядит более уместным, чем прямое использование cookies.

    После отображения идентификатора сессии каждый cookie в массиве cookies, пришедший с объектом запроса, отображается на странице наряду с его максимальным возрастом. Максимальный возраст изменяется и отображается снова, чтобы проверить новое значение, затем новый cookie добавляется в ответ. Однако ваш браузер может проигнорировать этот максимальный возраст; стоит поиграть с этой программой и поизменять значение максимального возраста, чтобы посмотреть поведение под различными браузерами.

    Заключение о JSP

    Этот раздел является только кратким обзором JSP, и даже с тем, что рассмотрено здесь (наряду с тем, что вы выучите о Java в остальной части книги, и вместе с вашим знанием HTML), вы можете начать писать замысловатые web страницы с помощью JSP. Синтаксис JSP не предназначен быть таинственным или сложным, так что если вы понимаете что было представлено в этом разделе, вы готовы к продуктивной работе с JSP. Вы можете найти больше информации в большинстве имеющихся книг о сервлетах или на java.sun.com.

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

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

    Упражнения

    1. Создайте JSP страницу, которая печатает строку текста, использующую тэг

    . Установите цвет этого текста случайным образом, используя код, встроенный в JSP страницу. Если у вас нет существующего JSP контейнера, вам необходимо загрузить, установить и запустить Tomcat с сайта jakarta.apache.org, чтобы иметь возможность запускать JSP.
  • Измените значение максимального возраста в Cookies.jsp и пронаблюдайте поведение в различных браузерах. Также обратите внимание на различие между повторным посещением страницы и выгрузкой/загрузкой браузера. Если у вас нет существующего JSP контейнера, вам необходимо загрузить, установить и запустить Tomcat с сайта jakarta.apache.org, чтобы иметь возможность запускать JSP.
  • Создайте JSP с одним полем, которое позволяет пользователю вводить время действия сессии, и со вторым полем, которое содержит данные, хранящиеся в сессии. Кнопка отсылки обновляет страницу и получает текущее время действия сессии и данные сессии, а потом помещает их в качестве значения по умолчанию в вышеупомянутые поля. Если у вас нет существующего JSP контейнера, вам необходимо загрузить, установить и запустить Tomcat с сайта jakarta.apache.org, чтобы иметь возможность запускать JSP.
  • Введение в JavaServer Faces 1.2: Часть 1. Создание простых приложений

    JSF для начинающих

    Подобно Swing и AWT, JSF представляет собой каркас разработки приложений, предоставляющий набор стандартных графических компонентов для создания интерфейсов. Но при этом JSF ориентирована на создание Web-приложений и имеет следующие преимущества:

    • Четкое разделение бизнес-логики и интерфейса
    • Управление сохраняемостью на уровне компонент
    • Простая работа с событиями на стороне сервера
    • Использование простых и знакомых концепций, таких как графический интерфейс или слои в Web-приложении
    • Доступность нескольких реализаций от различных компаний-разработчиков
    • Широкая поддержка со стороны интегрированных средств разработки (IDE)

    Как правило, приложение, созданное на основе JSF, состоит из следующих частей:

    • Объектов JavaBean, управляющих состоянием и поведением приложения
    • Компонентов GUI, с возможностью сохранения состояния
    • Классов, реализующих событийную модель, например, слушателей (listeners), аналогичных тем, что используются при традиционной разработке графических интерфейсов
    • Страниц, выступающих в роли представлений в парадигме Модель-Представление-Контроллер (Model-View-Controller — MVC). Подобные страницы могут обращаться к корневым узлам представления (view roots) через дерево компонентов JSF.

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

    Зачастую наибольшей трудностью при изучении JSF является осознание того, что компоненты обладают сохраняемым состоянием. Если вы когда-либо использовали Struts, повторите за мной: «JSF — это не Struts. JSF — это не Struts». Исходя из моих личных наблюдений, разработчики, имеющие опыт создания графических интерфейсов на Swing, AWT, Visual Basic или Delphi, испытывают меньше проблем при освоении JSF, чем те, которые годами использовали Struts и никогда не сталкивались с разработкой GUI. Данное руководство должно помочь вам привыкнуть к мысли о сохраняемости состояния компонент.

    JSF предоставляет описываемые тегами компоненты, соответствующие всем полям ввода в стандартном HTML. Кроме этого вы можете создавать специальные компоненты для нужд вашего приложения, а также комбинировать несколько компонент HTML в один сложный объект , например, элемент Data Picker, состоящий из трех выпадающих меню. Все компоненты могут сохранять свое состояние — это поддерживается на уровне самой технологии JSF. Кроме этого компоненты используются для динамической генерации HTML-страниц. Вдобавок к стандартным JSF-компонентам доступно множество других, предоставляемых сторонними разработчиками.


    JSF включает в себя:

    • Модель публикации событий
    • Простой контейнер для зависимых компонентов (inversion-of-control (IoC) container)
    • Компоненты, реализующие практически все стандартные возможности графических интерфейсов, включающие в себя:
      • Встраиваемую генерацию интерфейса
      • Валидацию на стороне сервера
      • Конвертирование данных
      • Управление переходами между страницами

    Являясь компонентной архитектурой, JSF легко расширяется и конфигурируется. Большинство функций JSF, например, навигация или управление объектами JavaBean, могут быть реализованы встраиваемыми компонентами. Подобная свобода встраивания компонент обеспечивает значительную гибкость при разработке Web-интерфейсов, а также позволяет легко использовать JSF совместно с другими компонентными технологиями. Например, можно заменить стандартную поддержку IoC в JSF на Spring, предоставляющую полновесное решение для обращения к объектам JavaBean как через IoC, так и с помощью аспектно-ориентированного программирования (AOP).

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

    JSF не имеет непосредственного отношения к JSP: она лишь использует JSP через специальную библиотеку тегов — своего рода мост. Жизненный цикл компонент JSF сильно отличается от цикла JSP-страниц. При этом технологию Facelets гораздо легче использовать вместе с JSF, т.к. она изначально проектировалась под нужды JSF, в то время как, интеграция JSF и JSP чем-то напоминает заколачивание шурупов молотком. Вам стоит обратить внимание на Facelets, особенно учитывая то, что возможности Facelets войдут в спецификацию JSF 2.0.

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

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

    Как правило, интерфейсы JSF-приложений создаются вообще без программирования на Java, и лишь слегка задействовав универсальный язык выражений (JSTL EL). Как уже отмечалось выше, существует множество IDE, облегчающих создание и сборку приложений JSF, а также множество сторонних компонент GUI. Но при этом можно работать без всякой поддержки со стороны каких-либо средств WYSIWYF, несмотря на то, что их использование изначально учитывалось при проектировании JSF. Этим мы и займемся в данной статье.

    Несмотря на то, что JSF изначально проектировалась с учетом будущей поддержки со стороны интегрированных сред WYSIWYG, ее преимущества доступны и без них. Даже если все делать вручную, использовать JSF все равно значительно проще других каркасов Web-приложений на Java. Таким образом, если вы ранее использовали WYSIWYG IDE, например, создавая интерфейсы Swing, то, скорее всего, вы будете продолжать использовать эти средства и с JSF. Если же нет, то и в случае JSF можно обойтись без WYSIWYG IDE. Только чистое программирование!

    В JSP 2.1 появилось множество новых возможностей, облегчающих поддержку JSF, таких как API универсального языка выражений (Universal Expression Language — EL), также появившегося в JSF 1.2. Теперь, в отличие от JSF 1.1 и JSP 2.0, можно использовать стандартные теги JST для итерирования по спискам и отрисовки компонент JSF. При этом, даже несмотря на все улучшения, использовать Facelets значительно удобнее, и множество идей Facelets позднее мигрировали в JSF 2.0.

    JSF проектировалась с учетом опыта накопленного в течение нескольких лет эволюции программных средств для разработки Web-приложений на Java. Все начиналось c JSP — технологии, обладающей немалыми достоинствами, но, к сожалению, позволяющей слишком легко смешивать код на Java с HTML-содержимым Web-страниц. Следующим шагом было появление так называемой «Модели 1» (Model 1), поощряющей перенос Java-кода в компоненты JavaBeans, к которым затем можно было обращаться на странице с помощью тега . Этот подход неплохо работал в случае простых Web-приложений, но раздражал многих Java-разработчиков своим сходством с C++, например, использованием статических директив include. В результате была предложена архитектура под названием «Model 2».

    Model 2 — это не что иное, как архитектура MVC, приспособленная под нужды Web-приложений. В соответствии с Model 2, контроллер представляет собой сервлеты (или Actions) а отображение страниц реализуется с помощью JSP-страниц. Примером упрощенной реализации Model 2 может служить Apache Struts — библиотека, использующая Actions в качестве сервлетов для контроллера. При этом логика поведения контроллера отделена от данных приложения, размещенных в объектах ActionForms. Struts в основном вызывал недовольство своей скорее процедурной, чем объектно-ориентированной моделью, чем заслужил прозвище «COBOL для Web». Другими примерами реализации Model 2 являются WebWork и Spring MVC, которые хотя и более объектно-ориентированны, но не получили такого широкого распространения, как Struts. При этом никто из них не содержит компонентной модели с сохраняемым состоянием, в отличие от JSF. Кстати, Struts2 был спроектирован на основе WebWork, отбросив таким образом первоначальный код Struts. Другими словами, Struts не нравится даже самим разработчикам Struts.

    Но главной проблемой Model 2 является то, что событийная модель носит слишком примитивный характер, являясь по суси сильно урезанной версией MVC. Кроме этого, не поддерживаются сохраняемые компоненты, что перекладывает слишком много работы на плечи разработчиков. Более мощная компонентная и событийная модель значительно облегчила бы взаимодействие на всех уровнях приложения. Кроме того, подобно JSP, большинство реализаций Model 2 эффективно не предотвращают смешивание разметки HTML и специальных тегов для отрисовки интерфейса приложения, которые ведут себя почти как компоненты, за исключением того, что не обладают сохраняемым состоянием. Наконец, некоторые реализации, например классический Struts, делают ошибку, разделяя поведение и состояние приложения, оставляя у многих Java-разработчиков ощущение, будто они программируют на COBOL.

    JSF — это не Struts. Забудьте о нем и начните изучение сначала
    JSF — это не реализация Model 2, ее возможности значительно шире. Многие думают, что поскольку изначальный автор Struts также возглавлял работу над спецификацией JSF, то предыдущий опыт работы с Struts должен пригодиться в проекте на JSF. Даже не пытайтесь программировать на JSF в стиле Struts. Так или иначе, вам придется забыть часть того, что вы знаете о Struts, чтобы эффективно изучать JSF.

    JSF предоставляет разработчикам компонентную модель и значительно лучшую поддержку MVC, чем реализация Model 2. Несмотря на то, что JSF спроектирована на основе протокола, не поддерживающего сохранение состояний, она значительно ближе к реальной парадигме MVC, чем архитектура Model 2. Кроме того, JSF помогает создавать более гибкие, лучше ориентированные на обработку событий графические интерфейсы, чем Model 2. В отличие от простой схемы «запрос — обработка», характерной для Model 2, JSF предлагает полноценный набор событий, таких как: выбор пункта меню, нажатие на кнопку, раскрытие узла в дереве и т.д.

    Гибко настраиваемая модель событий в JSF позволяет вашему приложению меньше зависеть от деталей HTTP и, как следствие, упрощает процесс разработки. JSF улучшает архитектуру приложений по сравнению с Model 2, помогая освободить классы контроллера и JSP-страницы от кода бизнес логики и представления (кроме того, из контроллера убирается еще и код представления). По правде говоря, классы, реализующие контроллер получаются легковесными и не привязанными к JSF вообще, что позволяет их легко тестировать. В отличие от полноценного MVC, ситуация, когда слой модели в JSF генерирует события, на которые должно отреагировать более чем одно представление, встречаются крайне редко (хотя в Crank пытаются реализовать поддержку нечто подобного, используя поддержку ajax4JSF в JBoss). Как уже отмечалось ранее, поддержка подобных возможностей необязательна, т.к. в случае Web нет поддержки сохранения состояния объектов на уровне протокола взаимодействия, поэтому события, инициирующие обновление представления, практически всегда (или может просто всегда?) представляют собой запрос от пользователя.

    В JSF-варианте MVC, связь между слоями модели и представления осуществляется через управляемые объекты JavaBean. В частности из-за этого, в эти объекты, привязанные к JSF, желательно не помещать ни бизнес логику, ни логику сохранения данных, а делегировать эти функции в слой модели самого приложения. В этом случае, к объектам приложения можно получать доступ через свойства управляемых объектов. Лично я предпочитаю разделять управляемые объекты на две категории: те, что привязаны к JSF и те, что нет. Последние я и буду называть объектами модели.

    В отличие от JSP, реализация слоя представления в JSF представляет собой компонентную модель, обладающую сохраняемым состоянием. Слой состоит из двух частей : корня представления и страниц JSP. Корень — это набор компонентов, в которых хранится общее состояние интерфейса. JSF, подобно Swing и AWT, управляет деревом компонентов в соответствии с паттерном «Компоновщик» (Composite). При этом контейнер, с помощью которого осуществляется управление содержащимися в нем компонентами, сам является компонентом. JSF свзязывает компоненты интерфейса с страницами JSP, позволяет ассоциировать поля ввода со свойствами объектов JavaBean (или скорее даже свойствами свойств), а кнопки — с обработчиками событий и методами, реализующими то или иное действие.

    На рисунке 1 изображена архитектура демонстрационного приложения (того самого, что мы подробно разберем ниже) с точки зрения парадигмы MVC:

    Если, дочитав до этого момента, вы пребываете в некотором недоумении — не волнуйтесь. Худшее уже позади. Понимание концепции JSF — это больше половины работы по ее реализации, и, как вы скоро увидите, игра стоит свеч. Но хватит теории, пора заняться непосредственно программированием!

    Разработка приложения с помощью JSF: шаг за шагом

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

    • Как лучше организовать структуру JSF-приложения для последующего разворачивания на сервере
    • Как описывать конфигурацию приложения в файле web.xml
    • Как использовать конфигурационный файл faces-config.xml
    • Как создавать управляемые объекты JavaBeans — так называемые объекты модели и контроллера
    • Как создавать слой представления, используя JSP
    • Как использовать библиотеки тегов для создания дерева компонентов, начиная от корневого узла слоя представления
    • Как производить валидацию по умолчанию для данных Web-форм

    Ниже мы будем последовательно улучшать наше приложение, используя все больше возможностей JSF. На рисунке 2 показано, как примерно будет выглядеть конечный вариант калькулятора. Весь исходный код доступен в разделе для скачивания.

    Сборка приложения с помощью Maven 2 и Eclipse WTP
    По умолчанию приложения будет собираться с помощью Apache Maven 2. При этом мы будем использовать структуру каталогов, являющуюся стандартной для Web-приложений Maven.

    Для начала нашей задачей будет создание простого Web-калькулятора, интерфейс которого представляет собой страницу, предлагающую пользователю ввести два числа для последующего сложения или умножения.

    Страница содержит следующие элементы:

    • Форму
    • Два текстовых поля
    • Две метки
    • Два элемента для вывода сообщений об ошибках
    • Две кнопки Submit
    • Панель для вывода результата

    Текстовые поля предназначены для ввода чисел, а метки — для задания их заголовков. В случае ошибок при валидации или конвертации данных сообщения будут выводиться в специальные элементы на странице. Всего приложение будет включать две JSP-страницы: calculator.jsp и index.jp, служащую исключительно для перенаправления пользователя на calculator.jsp. В качестве модели для страницы calculator.jsp будет выступать управляемый JavaBean Calculator . В данном простом примере мы пока не будем использовать контроллер, за исключением стандартного контроллера JSF.

    В целом, процесс разработки калькулятора будет состоять из следующих шагов:

    • Объявление описание сервлета Faces в дескрипторе Web-приложения (файле web.xml)
    • Описание местонахождения файла faces-config.xml внутри web.xml
    • Создание класса Calculator
    • Объявление Calculator в файле faces-config.xml в качестве объекта JavaBean
    • Создание страницы index.jsp
    • Создание страницы calculator.jsp

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

    Сам исходный код на Java будет размещен в каталоге src//main/java. Файл web.xml, а также конфигурационный файл JSF будут расположены в src/main/WEB-INF. Данный пример был создан с помощью среды Eclipse IDE для разработчиков Java EE (так называемая Eclipse JEE), которая включает в себя мастер для автоматической генерации файлов web/xml и faces-config.xml с заведомо верным набором элементов. Кроме этого предполагается, что для запуска будет использовать сервер приложений, поддерживающий Java EE 5, т.е. включающий в себя JAR-файлы для JSF и JSTL.

    Перед использованием Faces-сервлета необходимо объявить его в файле web.xml, как показано в листинге 1:

    В этом нет ничего нового, за исключением того, что вместо написания собственного сервлета, мы будем использовать стандартный JSF-сервлет для обработки запросов. Сервлет должен вызываться на каждый запрос со страниц JSP, на которых используется тег (в частности, мы будем применять его в Калькуляторе). Для этого необходимо добавить отображение сервлета (servlet mapping), указывающее, что через него должны загружаться только JSP-страницы, использующие JSF. Пример показан в листинге 2:

    Согласно отображению в web.xml, JSF контейнер будет вызывать сервлет Faces для обработки всех запросов, относительный URI которых начинается с /faces/ или заканчивается на *.jsf. Благодаря этому будет корректно инициализироваться контекст Faces и корневой элемент представления перед показом страниц JSF. Корневой элемент содержит дерево компонентов, а контекст Faces служит для взаимодействия приложения с JSF.

    Таким образом, URL для загрузки Калькулятора должен быть либо http://localhost:8080/calculator/pages/calculator.jsf либо http://localhost:8080/calculator/faces/pages/calculator.jsp, но ни в коем случае не http://localhost:8080/calculator/pages/calculator.jsp. В последнем случае JSP вызывается вне контекста JSF, а, следовательно, ни контекст Faces, ни корневой элемент представления не могут быть инициализированы.

    По умолчанию сервлет Faces будет пытаться использовать конфигурационный файл faces-config.xml, расположенный в директории WEB-INF Web-приложения. При этом можно использовать дополнительные конфигурационные файлы. Для этого предусмотрен специальный параметр в web.xml под названием javax.faces.application.CONFIG_FILES , в котором можно перечислить имена файлов, разделенные запятыми. Дополнительные файлы используются практически всегда за исключением простейших приложений. Но поскольку наш пример относится к последним, то назовем наш файл faces-config.xml и поместим его в /src/main/webapp/WEB-INF.

    Теперь мы создадим класс Calculator в стиле POJO (plain old Java object). Заметим, что сам класс никоим образом не зависит от JSF, но может быть использован в JSF-приложении с помощью механизма привязки (binding) методов и свойств. Наш класс содержит два свойства: firstNumber и secondNumber .

    Поскольку целью примера является всего лишь создание вашего первого JSF-приложения, то можно использовать максимально простую модель. В данном случае она представляет собой его один объект, показанный в листинге 3. Ниже мы разделим ее на два класса: контроллер и непосредственно класс модели.

    Код в листинге 3 настолько прост, что не нуждается в пояснениях. Напомним только, что сам по себе класс Calculator может использоваться вне JSF.

    Полностью содержимое файла faces-config.xml приведено в листинге 4. Как видите, немалая часть файла служит лишь для связывания файла с XML схемой Java EE JSF. Для объявления же управляемых объектов JavaBean служит элемент .

    Объявление управляемого объекта состоит из двух частей: имени объекта — calculator -, задаваемого с помощью элемента , и полного имени класса (элемент ). При этом класс управляемого объекта обязан содержать конструктор без параметров.

    Кроме вышеперечисленных элементов существует еще один — , который определяет, где JSF будет искать объект. В данном случае это request . Если объект привязан к представлению (как будет показано ниже) и еще не существует на момент обращения, то JSF создаст его автоматически с помощью API универсального языка выражений EL. Все объекты, помещаемые в request , доступны только в течение обработки одного запроса. Как правило, туда имеет смысл помещать объекты, чье состояние не представляет интереса после окончательного отображения страницы в конце обработки запроса.

    Страница index.jsp необходима, чтобы гарантировать, что calculator.jsp будет загружена в контексте JSF и благополучно найдет корневой элемент представления. Код index.jsp приведен в листинге 5:

    Как видите, все, что делает эта страница — это перенаправление к calculator.jsp, находящейся в каталоге faces , т.е. внутри контекста JSF. Благодаря этому, calculator.jsp получает доступ к корневому элементу представления.

    Данная страница занимает центральное место в слое представления Калькулятора. Страница содержит элементы для ввода двух чисел, как показано на рисунке 3:

    Полностью код страницы приведен в листинге 6:

    Большая часть файла представляет собой обычный HTML, а точнее XHTML. При этом можно вставлять HTML-содержимое внутрь тегов , и . То, что якобы невозможно смешивать теги HTML и JSF, является распространенным заблуждением. Как правило, это можно делать, за исключением компонента , который может содержать только другие компоненты в качестве дочерних элементов.

    Далее мы продемонстрируем процесс создания этой страницы шаг за шагом, потому как она достаточно сложна.

    Написание страницы начинается с объявления библиотек тегов для JSF, как показано в листинге 7:

    Код в листинге 7 содержит директивы для JSP компилятора, объявляющие, что будут использоваться две библиотеки тегов JSF: html и core . Библиотека html включает в себя теги для работы с формами и другими элементами HTML. Все теги, реализующие логику, валидацию данных, контроллер и т.д., включены в библиотеку core .

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

    Без этого JSF не сможет построить дерево компонентов или получить доступ к ранее созданному дереву. Пример использования приведет в листинге 8:

    Объявление делается в первой строчке листинга, после чего контейнер знает, что управление осуществляется с помощью JSF.

    Во второй строчке листинга 8 используется тег , указывающий JSF, что в этом месте необходима форма HTML. Во время отрисовки страницы JSF находит ранее созданные дочерние компоненты формы и вызывает их методы для генерации соответствующего HTML-кода. Компоненты формы могут располагаться на странице произвольным образом, например, так, как располагаются поля для ввода данных в Калькуляторе (см. листинг 9):

    Как и ранее, заметим, что в листинге преобладает HTML. В страницах JSF можно использовать любые элементы HTML — span , div , table — JSF не накладывает ограничений на работу дизайнера. Более того, есть даже программы, позволяющие создавать страницы JSF в Dreamweaver. Если же использовать JSF совместно с Facelets, что стало возможным, начиная с JSF 1.1, то работа дизайнера еще более упростится. Напомним, что технология Facelets войдет в состав JSF 2.0.

    Обратите внимание, что в листинге 9 в атрибутах values обоих тегов используется JSF EL (язык выражений JSF), например, value=»#» . На первый взгляд, эти выражения выглядят схоже с выражениями JSTL EL, однако, код JSF EL связывает поля ввода с соответствующими значениями свойств объектов JavaBean. Эта связь двунаправлена, т.е. если значение свойства firstNumber было 100, то в поле ввода будет выведено 100 при отображении страницы. Если пользователь ввел 200, то 200 будет сохранено в свойстве объекта (не учитывая возможности возникновения ошибок при конвертации и валидации данных — об этом мы поговорим позже).

    Кроме полей ввода в форме calcForm еще присутствуют три элемента типа commandButtons , задающие определенные действия (см. листинг 10):

    Внешний вид компонентов JSF определяется соответствующими классами из таблиц стилей. Каждый компонент связывается с встроенными (inline) стилями с помощью атрибутов style, а также содержит атрибут styleClass для задания класса CSS. Элемент , который будет рассматриваться в следующей секции, содержит атрибуты style для присвоения стилей строкам и столбцам таблицы. Далее мы рассмотрим использование каскадных таблиц стилей (CSS) в JSF.

    В листинге 10 показано, как связываются кнопки с методами add() , multiply() и clear() объекта calculator . Таким образом, при нажатии на кнопку будет вызван соответствующий метод (опять же, если не возникло ошибок конвертации или валидации).

    По умолчанию JSF производит валидацию данных формы перед вызовом метода, например add() или multiply() . Однако этот шаг можно пропустить, установив значение атрибута immediate в true, как сделано в листинге 10 для кнопки Clear. В этом случае JSF вызовет метод немедленно (здесь есть тонкости, но об это позже).

    Результаты операций сложения и умножения выводятся внутри тега с помощью элемента . Пример показан в листинге 11:

    Как и ранее, в коде страницы преобладает HTML. Обратите внимание, что можно свободно использовать выражения JSP внутри . Кроме того, аналогично другим компонентам JSF этот тег содержит атрибут rendered, управляющий выводом содержимого. Таким образом, секция отображения результата выводится только если значением выражения calculator.result != 0 is является true. В частности, по этой причине секция не отображается при первоначальной загрузке страницы, а выводится только после выполнения операции (если конечно результат не равен нулю). В этом решении есть определенная проблема: оно выносит логику приложения в слой представления. К тому же необходимо корректно показывать нулевой результат арифметических операций, таких как 0 + 0 или 0*7. Далее мы устраним этот недостаток.

    Если задаться целью переписать наше простое приложение на Struts, то, мне кажется, это потребует как минимум вдвое больше усилий. В этом случае понадобятся два класса Action , каждый со своим отображением (action mapping). В соответствии с рекомендацией Model 2, отображение также понадобится для перенаправления на исходную страницу при загрузке приложения. Обработка ошибок, которая делается по умолчанию в JSF, потребовала бы специального конфигурирования валидатора в Struts или же перегрузки метода validate в классе ActionForm . При этом пришлось бы выбрать один из трех вариантов: или использовать DynaValidatorForm в конфигурационном файле Struts, или создать класс-наследник ActionForm и переопределить метод validate , или класс-наследник ValidatorForm и работать с валидатором напрямую. Ну и, наконец, скорее всего бы пришлось определять переходы (по два на каждый action-класс или глобальные, используемые всеми классами). В общем, врагу не посоветуешь использовать Struts при разработке новых приложений.

    Для запуска приложения перейдите по адресу, соответствующему расположению WAR-файла приложения (у меня это http://localhost:8080/calculator0/). При этом index.jsp вызовет calculator.jsp внутри контекста JSF. Если вы используете среду Eclipse WTP и правильно настроили сервер приложений, то достаточно кликнуть правой кнопкой на calculator.jsp в панели навигатора и выбрать пункт Run As > Run On Server .

    Если в поле firstNumber или secondNumber ввести нечто, не являющееся числом, например, строку abc и нажать submit, то вновь будет вызвана страница calculator.jsp, а сообщение об ошибке будет выведено рядом с соответствующим полем ввода. То же самое произойдет, если одно из полей оставить пустым. Как видите, простая валидация выполняется в JSF практически автоматически, благодаря связыванию компонентов со свойствами, имеющими тип int . Поведение приложения при возникновении ошибок валидации и конвертации данных показано на рисунке 4:

    Как видите, сообщения об ошибках выглядят странно. Это сообщения по умолчанию, которые не предназначены для показа пользователю:

    • calcForm:firstNumber: ‘abc’ must be a number between -2147483648 and 2147483647 Example: 9346. Перевод: calcForm:firstNumber: ‘abc’ должно быть числом в диапазоне от -2147483648 до 2147483647. Например, 9346.
    • calcForm:secondNumber: Validation Error: Value is required. Перевод: calcForm:secondNumber: Ошибка валидации: Значение является обязательным для ввода.

    В следующей секции мы исправим эти сообщения.

    Если же вы ввели два значения, чья сумма или произведение не равны нулю, то результат должен быть схож с показанным на рисунке 5:

    Совершенствование Калькулятора

    В этом разделе мы несколько улучшим, а заодно и упростим интерфейс Калькулятора с помощью средств JSF. В частности, будет показано, как использовать CSS и интернационализированные (I18N) сообщения. Кроме этого, мы поработаем над сообщениями об ошибках, которые пока что оставляли желать много лучшего.

    До этого момента нам приходилось писать много HTML-кода. С одной стороны, используя HTML можно в точности добиться желаемой разметки, но с другой — для Web-приложения это может быть не настолько критично как, например, для рекламного проспекта. Поэтому можно облегчить создание интерфейса, используя компонент , позволяющий размещать дочерние элементы внутри ячеек таблицы.

    В листинге 12 показана обновленная версия страницы для ввода данных, созданная с помощью :

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

    Как видите, нам удалось избавиться практически от трети (около 20 строк) всего кода на странице и к тому же значительно улучшить читаемость. Теперь наше приложение глубже завязано на JSF, что, как правило, нравится программистам, и что крайне не любят Web-дизайнеры. Вообще, для каждого проекта важно найти оптимальный баланс между полным контролем над HTML-содержимым страниц и легкостью поддержки будущего приложения, достигающейся при помощи JSF-компонент.

    Тут мы впервые встретимся с некоторыми тонкостями использования JSF. Компонент может содержать только дочерние компоненты, в отличие от , и , внутрь которых можно также помещать обычные фрагменты HTML. Первый элемент на странице включает в себя три колонки, поэтому добавление более трех дочерних компонентов приведет к появлению новой строки. Второй элемент включает в себя только одну колонку, поэтому каждый из дочерних компонентов отображается в отдельной строке. При выводе страницы преобразуется в таблицу HTML, так что, с точки зрения пользователя, результат будет практически идентичен тому, что было раньше. Еще раз повторим: дочерними элементами могут быть только компоненты JSF. Обычный HTML, добавленный внутрь будет проигнорирован при отрисовке страницы.

    Если у вас есть опыт использования HTML и CSS, то вы, наверное, представляете, как улучшить интерфейс первой версии Калькулятора. То же самое можно делать и при использовании . Все что требуется — это импортировать таблицу CSS и можно начинать использовать стили внутри . В данном случае мы добавим окантовку к таблице и будем чередовать белый и серебряный фон строк.

    Первым делом надо объявить импортирование таблицы стилей, как показано в листинге 14:

    Сама таблица приведена в листинге 15:

    В листинге 15 показаны определения стилей oddRow и evenRow . Они задают белый фон нечетных строк и серебряный фон четных строк соответственно.


    Теперь применим эти стили к , как показано в листинге 16:

    Чтобы применить стили к строкам таблицы необходимо установить значение атрибута rowClasses в oddRow, evenRow . Стиль, определяющий внешнюю рамку для таблицы, применяется с помощью атрибута styleClass ( style ). В результате должен выглядеть как в листинге 17:

    А сам интерфейс Калькулятора должен принять вид как на рисунке 6:

    предоставляет гораздо больше возможностей по поддержке стилей, чем рассматривается в данной статье. За более полной информацией обратитесь к описанию API библиотеки тегов.

    Если бы все пользователи были своего рода технофилами, то, может, их и устроили бы сообщения об ошибках, в противном же случае они малоинформативны. Но это можно исправить несколькими способами. Начнем с добавления метки, как показано в листинге 18:

    Обратите внимание на значение «First Number» атрибута label в . Теперь при возникновении ошибки сообщение будет выглядеть как на рисунке 7:

    Теперь в сообщении используется текст метки вместо имени свойства, что значительно понятнее для пользователя. Но, впрочем, поскольку сообщение в любом случае выводится рядом с полем ввода, то название поля можно и вовсе опустить. К тому же сами сообщения слишком длинные. Их можно укоротить, как показано в листинге 19:

    В листинге 19 значения атрибутов showSummary и showDetail компонента устанавливаются в значения true и false соответственно. Теперь при ошибке валидации firstNumber сообщение будет выглядеть как: «First Number: ‘aaa’ must be a number consisting of one or more digits.» — а в случае пустого поля secondNumber будет выведено: «Second Number: Validation Error: Value is required». Впрочем, сообщения можно еще улучшить, как будет показано ниже.

    В JSF 1.2 были добавлены атрибуты requiredMessage и conversionMessage , так что теперь можно переопределять текст сообщений индивидуально для каждого компонента (см. листинг 20):

    Обратите внимание на значения атрибутов requiredMessage=»required» converterMessage=»not a valid number» компонентов . Теперь сообщения об ошибках хорошо вписываются в : они выводятся рядом с полями ввода, так что пользователю понятно, к чему они относятся (см. рисунок 8):

    К сожалению, у этого подхода есть один недостаток: приходится устанавливать значения атрибутов у каждого поля ввода. В простом примере это несложно, но грозит серьезными трудностями при поддержке крупного приложения. Очевидно, что это приводит к определенной избыточности, т.е. нарушает принцип «не повторяйся» (don»t repeat yourself или сокращенно — DRY).

    Сообщениями можно управлять глобально, для этого следует определить набор ресурсов (resource bundle) в файле faces-config.xml и использовать его для хранения текстов сообщений. Пример приведен в листинге 21:

    Содержимое файла message.properties показано в листинге 22:

    Теперь для изменения сообщения об ошибке конвертации или валидации для любого поля ввода достаточно просто поменять текст в глобальном файле ресурсов.

    Замечание: Если вы работаете в среде Eclipse JEE, не забудьте добавить src/main/resources/messages.properties в список каталогов с исходным кодом.

    В этом разделе мы улучшили логику представления интерфейса нашего приложения. Далее мы добавим класс-контроллер — CalculatorController , который будет содержать ссылку на объект Calculator , используя механизм инъекции зависимостей (далее dependency injection).

    Добавление контроллера

    Далее мы чуть изменим наше приложение, чтобы класс Calculator оставался в виде POJO и не был привязан к JSF. Для этого мы создадим класс-контроллер, который будет управлять объектами модели. Таким образом, от JSF будет зависеть только контроллер, а не слой модели приложения.

    В этом разделе будет рассмотрено:

    • Использование механизма dependency injection в JSF
    • Работа с объектом facesContext
    • Добавление объектов FacesMessage
    • Использование элемента
    • Связывание компонентов с контроллером

    Все эти возможности будут использованы в нашем примере. Затем мы остановимся на каждой из них в отдельности и рассмотрим более подробно.

    В листинге 23 приведен метод divide() класса Calculator . Далее мы покажем, как корректно обрабатывать ошибки деления на ноль, выводя сообщения для пользователя с помощью объекта FacesMessage :

    Теперь мы создадим новый класс — CalculatorController , содержащий ссылку на POJO-класс Calculator .

    CalculatorController также связан с тремя компонентами JSF — другими словами, он зависит от классов, являющихся частью JSF. Кроме этого, он отвечает за обработку исключений путем добавления объектов типа FacesMessage в FacesContext .

    CalculatorController содержит ссылки на следующие компоненты JSF:

    • resultsPanel — компонент типа UIPanel
    • firstNumberInput — компонент типа UIInput
    • secondNumberInput — компонент типа UInput

    Обработка ошибок в Калькуляторе показана на рисунке 9:

    На рисунке 10 показано сообщение об успешном выполнении операции:

    Класс CalculatorController , показанный в листинге 24, позволяет объектам модели приложения оставаться независимыми от JSF. В тоже время он сам является JSF-зависимым объектом, хранит ссылки на компоненты интерфейса, а также отвечает за обработку ошибок и формирование сообщений о статусе операции.

    Далее мы изменим страницу calculator.jsp, чтобы она, во-первых, отображала сообщения об ошибках при выполнении операций, а во-вторых, обращалась к объекту контроллера, а не непосредственно к объекту POJO-класса Calculator . Код страницы приведен в листинге 25:

    Далее необходимо добавить описание контроллера в файле faces-config.xml и связать его с объектом calculator через dependency injection (см. листинг 26):

    Таким образом, изменения затронули все слои приложения. Пришло время остановиться на них поподробнее.

    JSF поддерживает dependency injection — механизм, с помощью которого ссылки на одни объекты JavaBean можно сохранять в свойствах других подобных объектов. Поскольку в данном случае объект calculator будет доступен только через внешний объект calculatorController , мы поместим его в область видимости none . Это означает, что объект не будет помещен ни в какую специальную область видимости после создания. Фрагмент файла faces-config.xml, описывающий calculator , приведен в листинге 27:

    Объект calculatorController будет помещен в область видимости request . При этом ссылка на calculator будет передана в calculatorController . Это делается с помощью выражения # в теге . Таким образом, JSF создаст экземпляр класса Calculator и передаст его в метод setCalculator класса CalculatorController , как показано в листинге 28:

    Объект calculator используется классом CalculatorController , но при этом сам остается «чистым», т.е. никоим образом не привязанным от JSF. Классы модели всегда желательно держать независимыми от библиотек, подобных JSF, изолируя весь JSF-зависимый код внутри контроллера, в данном случае — классе CalculatorController . Это значительно облегчает тестирование и повторное использование модели.

    Класс CalculatorController тесно связан с JSF — это особенность архитектуры приложения. К нему привязаны три компонента JSF. Один из них — resultsPanel , представляющий собой секцию для вывода результатов арифметических операций, покзан в листинге 29:

    За привязку resultsPanel к CalculatorController отвечает JSF. Обратите внимание на атрибут binding в листинге 30:

    Значением это атрибута является выражение «#» , связывающее свойство resultsPanel с компонентом. JSF сохраняет ссылку на компонент в этом свойстве, вызывая метод calculateController.setResultsPanel при загрузке страницы. Таким образом, JSF позволяет легко манипулировать элементами интерфейса, не требуя явного обхода или поиска в дереве компонентов.

    На самом деле, сначала JSF вызывает метод calculateController.getResultsPanel . Если компонент уже создан, то он будет использован в представлении. Если же метод вернул null , то JSF создаст новый экземпляр компонента, а затем передаст его в метод calculateController.setResultPanel , привязав таким образом к объекту контроллера.

    В листинге 31 показано, как компонент resultsPanel используется внутри метода CalculateController.add() :

    Если вы используете некое решение для поддержки Ajax, например, JBoss Ajax4Jsf, то для реализации частичной загрузки страниц не потребуется больших усилий (при этом Ajax4Jsf необходим только до выхода JSF 2.0, который будет включать всю необходимую функциональность). С точки зрения пользователя, приложение будет выглядеть как апплет или созданное с помощью Flex. И на JavaScript ничего писать не придется!

    Как видно из листинга, если метод calculator.add отрабатывает успешно, то CalculateController.add вызывает resultsPanel.setRendered(true) , делая панель результата видимой для пользователя. В противном случае происходит вызов resultsPanel.setRendered(false) и панель не выводится.

    Это очень важный момент, на нем имеет смысл остановиться подробнее. JSF — это компонентная технология, все компоненты в ней обладают сохраняемым состоянием. Таким образом, больше не требуется специальный код, управляющий состоянием компонентов, как в первоначальном примере. Достаточно один раз скрыть или деактивировать компонент, и он будет скрыт или неактивен при последующих перезагрузках представления. Подобное поведение значительно ближе к традиционному GUI, чем различные реализации Model 2. Используя JSF, вы пишете меньше кода, а соответственно , тратите меньше времени на разработку Web-приложений. JSF делает из Web-приложений настоящие приложения . Имейте это в виду.

    JSF предоставляет средства для показа сообщений пользователям о статусе той или иной операции. Для добавления сообщений используется класс FacesContext , благодаря которому они впоследствии могут быть выведены с помощью тега .

    JSF хранит объект класса FacesContext в переменной ThreadLocal . К ней можно получить доступ, вызвав статический метод FacesContext.getCurrentInstance() . В методе add() в FacesContext добавляются сообщения, которые должны быть доступны до конца обработки запроса. Пример показан в листинге 32:

    В данном примере сообщения представляют собой объекты класса FacesMessage , добавляемые в объект facesContext . При этом уровень важности сообщения зависит от возникновения исключений при выполнении операции суммирования. Если оно прошло успешно, то уровень будет INFO , в противном случае — ERROR .

    Сообщения выводятся на странице с помощью тега , как показано в листинге 33:

    Для вывода только глобальных сообщений, т.е. не относящихся к конкретному компоненту, можно установить значение атрибута globalOnly в true . К таковым относятся сообщения, добавляемые в листинге 32. Обратите внимание, что стиль сообщений об ошибках отличается от стиля обычных статусных сообщений.

    Поскольку контроллер имеет дело с компонентами, он может менять их значения, а также инициализировать в соответствии с логикой представления. Поэтому, в случае выброса исключения при попытке деления на ноль в методе divide, контроллер может его обработать, установив значение компонента secondNumberInput в 1.

    Для начала необходимо привязать компонент secondNumberInput к объекту класса CalculatorController , как показано в листинге 34:

    Теперь этот компонент можно использовать по своему усмотрению. Например, присвоить ему значение 1 в случае выброса исключения при попытке деления на ноль (см. листинг 35):

    Очень важно постоянно помнить, что JSF значительно ближе к компонентной модели GUI, чем к некой запутанной реализации Model 2. Это открывает потенциально широкие возможности. В частности, можно манипулировать значением компонента secondNumberInput в листинге 35, потому что это объект, а не просто кусок HTML или JSP-кода. Его можно модифицировать и он запомнит новое значение. У него есть состояние.

    Как правило, значениями атрибутов JSF могут быть выражения. Поэтому, если необходимо, например, поменять цвет метки на красный при возникновении ошибки, это можно несложно сделать. Пример приведен в листинге 36:

    Обратите внимание, что значением атрибута styleClass является выражение # , при вычислении которого будет вызван метод, приведенный в листинге 37:

    В листинге 37 показано, как можно менять класс CSS в зависимости от того, является ли значение компонента firstNumbedInput корректным.

    JSF включает в себя механизм навигации, аналогичный Struts. Он определяет связь между логическим признаком результата и следующим представлением. Ниже мы добавим поддержку навигации в Калькулятор.

    Навигация осуществляется с помощью правил перехода. На рисунке 11 показаны правила, которые будет использоваться в Калькуляторе:

    Как правило, диаграмму переходов Web-приложения удобнее создавать с помощью специальных средств. В частности, многие IDE предоставляют такие возможности для JSF-приложений. Eclipse JEE включает в себя Navigation Rule Layout Tool, пример использования которого показан на рисунке 12:

    Рисунки 11 и 12 должны стать намного понятнее после прочтения данного раздела.

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

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

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

    • С помощью commandLink и обычного правила перехода
    • С помощью commandLink и правила перехода, использующего элемент
    • С помощью outputLink

    Первый способ реализуется путем добавления правила перехода в файл faces-config.xml, как показано в листинге 38:

    Правило в листинге 38 указывает JSF, что после любого действия (action), чьим результатом является логический признак CALCULATOR , необходимо загрузить /pages/calculator.jsp в качестве представления. Данное правило является динамическим, т.е. оно применимо к любому действию, возвращающему CALCULATOR . Исключением является случай, когда можно применить более конкретное правило, например, связанное с конкретным представлением с помощью элемента (на этом мы остановимся позже). Таким образом, правило приведенное в листинге 38 аналогично глобальным переходам (global forwards) в Struts.

    На странице необходимо добавить элемент в качестве дочернего к , как показано в листинге 39:

    Все работает, как и должно: по данной ссылке загружается главная страница Калькулятора. Однако пользователя может смутить то, что в адресной строке браузера по-прежнему фигурирует http://localhost:8080/calculator3/home.jsf. Для кого-то это может показаться нормальным, особенно для людей, часто работающих с Web-приложениями. Но это может помешать сохранить страницу Калькулятора в закладках браузера, т.к. ее подлинный адрес неизвестен.

    Это можно поправить с помощью элемента в правиле перехода, описанном в faces-config.xml (см. листинг 40):

    по-прежнему использует правило перехода, используя атрибут action. Теперь при нажатии на ссылку браузер будет перенаправлен на страницу Калькулятора.

    Таким образом, проблема решена за счет дополнительного обращения к серверу, что может занимать какое-то время в условиях медленного соединения. Однако если вы разрабатываете приложения для работы в Интранет, то это не должно стать проблемой.

    Этого дополнительного запроса можно избежать, если вы не против разместить прямую ссылку на требуемую страницу, как показано в листинге 42:

    В листинге 42 показана прямая ссылка на следующее представление, что, как правило, считается признаком плохого стиля при использовании Model 2 и JSF. Желательно, чтобы у контроллера была возможность инициализировать классы модели для следующего представления, поэтому лучше делать не прямой вызов, а через какой-либо action-метод контроллера. Но если нужна просто ссылка и правильный адрес в браузере, то в листинге 42 показано, как это сделать.

    Долгое время сохранять ссылки на JSF-приложения в закладках было достаточно проблематично. Некоторые библиотеки, например, JBoss Seam, предлагали свои решения этой проблемы. Ей также будет уделено внимание в следующей версии JSF — JSF 2.

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

    Согласно данному правилу, если текущим представлением является calculator.jsp, а action-метод возвращает признак results , то должен быть выполнен переход к странице результатов (results.jsp). JSF автоматически преобразовывает возвращаемые значения action-методов к строковому виду и использует их для выбора следующего представления. Методы могут возвращать значения любых типов, потому как для преобразования используется метода toString . Например, многие используют перечисления ( Enum .)

    Далее мы изменим выходные значения всех операций на results . Пример метода add() приведен в листинге 44:

    Обратите внимание, что метод add() возвращает строку results , связанную со страницей results.jsp. В то же время обработчик нажатия на кнопку Cancel не возвращает results . В случае если метод возвращает значение, не связанное ни с одним правилом перехода, то JSF не меняет текущее представление.

    Можно сделать правило еще более специализированным, как показано в листинге 45:

    Однако в этом случае придется создавать по правилу на каждый метод. Это может привести к ненужному дублированию.

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

    Отметьте, что значением атрибута value является HOME . В листинге 47 показано правило перехода, связывающее значение HOME с домашней страницей приложения:

    Как видите, с точки зрения правил перехода и вызова обработчиков, элементы и работают совершенно одинаково.

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

    Правило для перехода к главной странице может быть описано двумя способами. Первый способ, показанный в листинге 49, очень похож на рассматривавшийся ранее:


    Данное правило гласит, что если текущим представлением является страница результатов (/pages/results.jsp) и обработчик возвращается строку calculator , то необходим переход на главную страницу (/pages/calculator.jsp). Но иногда требуется правило более общее, чем приведенное в листинге 49, но все же более конкретное, чем глобальный переход. В этом случае можно использовать решение, показанное в листинге 50:

    Как видно из листинга, можно определять логические области внутри приложения и описывать применимые к ним правила.

    Заключение

    В статье была рассмотрена технология JSF и ее компонентная архитектура, схожая с Swing, SWT и AWT, благодаря которой разработка приложений больше напоминает создание традиционных приложений GUI, чем Web-приложений. JSF-приложения, написанные на JSF, как правило короче, проще для понимания, и их легче поддерживать, чем их аналоги созданные в стиле Model 2. В настоящее время JSF привлекает к себе все больше внимания со стороны Java-разработчиков, что отражается и в требованиях при принятии на работу.

    В настоящее время идет работа над JSF 2, которая будет включать поддержку Facelets, Ajax, а также в целом облегчит создание компонентов. JSF 2 должна еще повысить положительный эффект от изучения JSF. Помимо всего прочего, в JSF 2 ожидается поддержка частичной загрузки страниц через Aajx, что в настоящее время реализуемо только с помощью сторонних библиотек, например, Ajax4JSF.

    При этом вышесказанное не означает, что у JSF нет конкурентов. Из серверных компонентных технологий неплохо выглядит Tapestry 5, однако она несовместима с Tapestry 4. Также серьезный, но пока недостаточный для широкого распространения, интерес вызывает Wicket.

    Вдобавок существуют некомпонентные серверные решения, в частности, Struts 2.x, который сильно улучшил WebWork. Некоторые разработчики возлагают большие надежды на Struts 2.x, несмотря на то, что он создан на основе WebWork, а не Struts 1.x. Кроме этого, продолжает развиваться проект Spring MVC, который может быть неплохим вариантом, если не требуется поддержка серверных компонент GUI.

    Наконец, существуют клиентские технологии, которые делегируют все вызовы к серверной части. Примерами являются Google Web Toolkit (GWT) и Adobe Flex. Их архитектуры сильно отличаются от JSF, но они предназначены для использования в схожих приложениях. У них есть свои преимущества и недостатки, и они могут оказать определенное влияние на распространение JSF.

    Но, тем не менее, JSF, скорее всего, будет продолжать успешно развиваться, во-первых, потому что это стандарт для Java EE, а во-вторых, благодаря активному сообществу разработчиков. Интерес к JSF превышает интерес к Tapestry, Spring MVC, Java Flex и GWT, а JSF 2.0 может стать дополнительным стимулом к применению данной технологии.

    Во второй статье серии мы расскажем о жизненном цикле приложений на JSF, а также рассмотрим вопросы работы с валидаторами, конвертаторами данных, слушателями фаз (phase listeners) и другими продвинутыми возможностями JSF.

    Вопросы и ответы на собеседование по теме Java Server Pages (JSP)

    Вопросы и ответы на собеседование по теме Java Server Pages (JSP).

    к списку вопросов раздела JEE

    Вопросы

    1. Что такое jsp и зачем он нужен?
    2. Расскажите об этапах (фазах) жизненного цикла jsp.
    3. Расскажите о методах жизненного цикла jsp.
    4. Какие методы жизненного цикла JSP могут быть переопределены?
    5. Как можно предотвратить прямой доступ к JSP странице из браузера?
    6. Как закомментировать код в jsp?
    7. Объясните Scriptlet, Expression и Declaration в JSP.
    8. Какие неявные, внутренние объекты и методы есть на jsp странице?
    9. Почему неявные объекты не доступны в обычной JSP странице?
    10. Что вы знаете о PageContext и какие преимущества его использования?
    11. Как сконфигурировать init параметры для JSP?
    12. Почему не рекомендуется использовать скриптовые элементы в jsp?
    13. Можем ли мы определить класс внутри JSP страницы?
    14. Какие есть способы вставки java кода в jsp страницу?
    15. Как можно запретить использование скриптов и java кода на jsp странице?
    16. Что вы знаете о jsp тегах? Объясните как вы понимаете Action tag и JSP Action Elements.
    17. Какая разница между директивой include и jsp:include action?
    18. Что вы знаете о языке выражений jsp (JSP Expression Language – EL)?
    19. Назовите неявные, внутренние объекты JSP EL и их отличия от объектов jsp.
    20. Как узнать имя http метода используя JSP EL?
    21. Что такое JSTL (Jsp Standard tag library)?
    22. На какие категории можно разделить JSTL теги, приведите примеры.
    23. Что вы знаете о написании пользовательских jsp тегов?
    24. Приведите пример использования собственных тегов.
    25. Почему не нужно конфигурировать стандартные JSP теги в web.xml?
    26. Как можно обработать ошибки jsp страниц?
    27. Как происходит обработка ошибок с помощью jstl?
    28. Как сделать «новую линию в HTML» в JSP?
    29. Приведите пример конфигурации JSP в дескрипторе развертывания.
    30. Как деактивировать использование EL на JSP?
    31. Когда контейнер проинициализирует множество JSP/Servlet объектов?
    32. Можно ли использовать javascript на jsp странице?
    33. Всегда ли создается объект сессии на jsp странице, можно ли отключить его создание?
    34. Какая разница между JspWriter и Servlet PrintWriter?
    35. Как можно расширить функциональность jsp?
    36. Best Practices в JSP.

    Ответы

    1. Что такое jsp и зачем он нужен?

    JSP — это JavaServer Pages. JSP является серверной технологией для создания динамических веб-страниц. JSP расширяет технологию сервлетов, чтобы помочь разработчикам создавать динамические страницы с HTML подобным синтаксисом.

    Создание представлений поддерживается и в сервлетах, но в таком случае код выглядит ужасным и подвержен ошибкам. Так же было замечено, что большинство элементов веб страницы является статическими и поэтому JSP страница больше подходит к веб-страницам. По возможности необходимо избегать бизнес логики на странице JSP и использовать страницу только в качестве представления. Поэтому рекомендуется использовать JSP actions элементы или JSTL теги вместо написания JSP скриптов.

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

    2. Расскажите об этапах (фазах) жизненного цикла jsp.

    Если посмотреть код внутри созданной JSP страницы, то он будет выглядеть как HTML и не будет похож на java класс. Конвертацией JSP страниц в HTML код занимается контейнер, который так же создает сервлет для использования в веб приложении. Жизненный цикл JSP состоит из нескольких фаз:

    1. Translation – JSP контейнер проверяет код JSP страницы, парсит ее для создания кода сервлета. К примеру, в Tomcat вы можете найти классы сервлетов в директории TOMCAT/work/Catalina/localhost/WEBAPP/org/apache/jsp. Если страница JSP называется home.jsp, то созданный сервлет обычно будет иметь имя home_jsp и имя файла — home_jsp.java.
    2. Compilation – JSP контейнер компилирует исходный код jsp класса и создает класс на этой фазе.
    3. Class Loading – контейнер загружает классы в память на этой фазе.
    4. Instantiation – внедрение конструкторов без параметров созданных классов для инициализации в памяти классов.
    5. Initialization – в контейнере вызывается init метод объекта JSP класса и инициализируется конфигурация сервлета с init параметрами, которые указаны в дескрипторе развертывания (web.xml). После этой фазы JSP способен обрабатывать запросы клиентов.Обычно эти фазы происходят после первого запроса клиента (т.е. ленивая загрузка), но можно настроить загрузку и инициализацию JSP на старте приложения по аналогии с сервлетами.
    6. Request Processing – длительный жизненный цикл обработки запросов клиента JSP страницей. Обработка является многопоточной и аналогична сервлетам — для каждого запроса создается новая нить, создаются объекты ServletRequest и ServletResponse и происходит внедрение сервис методов JSP.
    7. Destroy – последняя фаза жизненного цикла JSP на которой JSP класс удаляется из памяти. Обычно это происходит при выключении сервера или андеплое приложения.

    3. Расскажите о методах жизненного цикла jsp.

    Жизненные циклы методов JSP:

    • jspInit() — метод объявлен в JSP странице и реализуется с помощью реализаций контейнера. Этот метод вызывается один раз в жизненном цикле JSP для того, чтобы инициализировать конфигурационные параметры, указанные в дескрипторе развертывания. Этот метод можно переопределить с помощью определения элемента JSP scripting и указания необходимых параметров для инициализации.
    • _jspService() — этот JSP метод внедряется JSP контейнером для каждого запроса клиента с помощью передачи объекта запроса и ответа. Отметьте, что имя метода начинается с нижнего подчеркивания и отличается от других методов жизненного цикла тем, что его невозможно переопределить. Весь JSP код проходит через этот метод и он переопределен по умолчанию. Этот метод определен в HttpJspPage интерфейсе.
    • jspDestroy() — метод вызывается контейнером JSP для удаления объекта из памяти (на последней фазе жизненного цикла JSP — Destroy). Метод вызывается только один раз и мы можем его переопределить для очищения любых ресурсов, которые были созданы в JSP init методе.

    4. Какие методы жизненного цикла JSP могут быть переопределены?

    Мы можем переопределить jspInit() и jspDestroy() методы с помощью использования скриптов JSP. Метод jspInit() переопределяется для создания общих ресурсов, которые мы хотели бы использовать в методе обслуживания JSP, а jspDestroy() метод переопределяется, чтобы освободить общие ресурсы на фазе уничтожения.

    Две модели JSP

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

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

    Аббревиатура JSP расшифровывается как Java Server Pages, или, говоря по-русски, серверные страницы на Java. Суть этой технологии заключается в том, что она позволяет использовать код, написанный на Java, внутри HTML-страниц, чтобы путём комбинирования Java и HTML создавать полноценные современные web-приложения.

    Если вы думаете, что суть JSP есть мешанина из Java и HTML-кода, то вы немного ошибаетесь (хотя, конечно, именно так можно подумать из того, что изложено выше). В современных web-приложениях, написанных с использованием JSP, применяется только HTML-код, однако синтаксис этого HTML несколько расширен, по сравнению с обычными гипертекстовыми страницами. Расширен именно для того, чтобы можно было вызывать код Java-приложения при обработке HTML-страниц. На практике это реализуется в виде специальных тегов, которые распознаются в процессе обработки страницы и через которые вызывается Java-код, находящийся во внешних по отношении к самой странице модулях. Возможно, вам покажется, что такой подход неоправданно сложен, однако на самом деле это не так — а почему именно это не так, я объясню ниже.

    Справедливости ради стоит заметить, что внедрять Java-код внутрь JSP-страницы напрямую действительно можно. Это называется JSP-скриптингом (JSP Scipting; к сожалению, адекватного русскоязычного термина, который был бы полностью аналогичен англоязычному, подобрать нельзя). Тем не менее, в современных web-приложениях JSP-скриптинг практически не используется, и тому есть ряд вполне веских причин, которые мы с вами обсудим чуть ниже.

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


    Шаблон проектирования MVC

    В современном процессе разработки любых приложений самым активным образом применяются шаблоны проектирования (англ. design patterns). Переоценить их удобство и полезность трудно, а потому везде, где можно, их стараются применять. Для web-приложений практически идеальным стал шаблон MVC, Model-View-Controller, или, если по-русски, модель-представление-контроллер (встречается, но весьма редко, также вариант перевода модель-представление-поведение).

    Конечно, этот шаблон проектирования заслуживает отдельной статьи, и даже, наверное, не одной, однако сейчас я постараюсь кратко рассказать, в чём же состоит его суть.

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

    Конечно, это всё выглядит, на первый взгляд, как бесконечно далёкая от реальной жизни абстракция, однако на самом деле это не совсем так. В реальных web-приложениях шаблон Model-View-Controller используется активно и успешно, и именно в его использовании и состоит преимущество JSP перед тем же, например, PHP.

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

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

    Таких моделей не сказать чтобы много — их всего две. Они, в общем-то, так и называются: JSP Model 1 и JSP Model 2 (их схемы приведены на иллюстрациях к статье). Давайте сначала рассмотрим каждую из них, а потому уже поговорим об их достоинствах и недостатках.

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

    В JSP Model 2, в отличие от JSP Model 1, мы видим на схеме полноценную реализацию шаблона модель-представление-контроллер. Именно эти части приложения в ипостаси сервлета (контроллер), JavaBean-классов (модель) и JSP-страниц (представление) можно увидеть на предлагаемой схеме внутри приложения. Как видно из всё той же схемы, при запросе пользователя первым реагирует сервлет, который, взаимодействуя сложным образом с другими компонентами приложения, получает, наконец, из базы данных через JavaBean-классы какую-то информацию (либо же записывает её туда, что сейчас не столь уж принципиально), которая затем передаётся JSP-страницей в качестве ответа на пользовательский запрос.

    В общем-то, говоря о специфике каждой из моделей web-приложений на JSP, стоит отметить, в первую очередь, что JSP Model 1 является моделью, ориентированной на JSP-страницы, которые и осуществляют основную работу в программе. Вся бизнес-логика приложения присутствует в явном или неявном виде на JSP-странице, что вряд ли можно считать плюсом. Что касается JSP Model 2, то здесь, позволю себе повториться, мы имеем дело с шаблоном модель-представление-контроллер. О преимуществах его использования я довольно-таки подробно рассказывал выше, однако здесь стоит упомянуть ещё некоторые из них. Во-первых, с приложениями, организованными по JSP Model 2, гораздо проще иметь дело при проведении каких-то изменений непосредственно на самих JSP-страницах. Мы вольны менять их, в общем-то, практически так, как захотим, без оглядки на такие мелочи жизни, как контроллер и модель. Модульность позволяет нам не затрагивать бизнес-логику при изменении пользовательского интерфейса. Кроме того, разработчик, работающий над реализацией бизнес-логики, может совершенно не задумываться над проблемами реализации интерфейса, равно как и разработчик, реализующий интерфейс, может не особенно беспокоиться насчёт бизнес-логики разрабатываемого командой приложения.

    В общем-то, из всего сказанного выше можно сделать только один вывод: возникшая исторически раньше JSP Model 1 в наше время уже не так актуальна, как JSP Model 2. И дело здесь, в общем-то, не в росте размеров проектов, которые пишутся с использованием JSP: JSP Model 2 будет удобнее и на большинстве небольших проектов, поскольку эта модель гибче, чем JSP Model 1.

    Что касается самой технологии JSP, то, конечно, эта статья не может рассматриваться как хороший старт для того, кто ещё ни разу ничего не писал с использованием этой технологии, в силу некоторой своей абстрактности. Тем не менее, я надеюсь на то, что она поможет начинающим изучать JSP глубже понять некоторые особенности построения web-приложений на основе этой технологии, а также привлечёт их внимание к тому факту, что в современной индустрии разработки программного обеспечения шаблоны проектирования играют очень и очень важную роль.

    Предисловие

    Технология проектирования Java Server Pages (JSP) — это одна из технологий J2EE, которая представляет собой расширение технологии сервлетов для упрощения работы с Web-содержимым. Страницы JSP позволяет легко разделить Web-содержимое на статическую и динамическую часть, допускающую многократное использование ранее определенных компонентов. Разработчики Java Server Pages могут использовать компоненты JavaBeans и создавать собственные библиотеки нестандартных тегов, которые инкапсулируют сложные динамические функциональные средства.

    Спецификация Java Server Pages (http://java.sun.com/products/jsp) наследует и расширяет спецификацию сервлетов (http://java.sun.com/products/servlets). Как и сервлеты, компоненты JSP относятся к компонентам Web и располагаются в Web-контейнере. Страницы JSP не зависят от конкретной реализации Web-контейнера, что обеспечивает возможность их повторного использования.

    В дополнение к классам и интерфейсам для программирования сервлетов (пакеты javax.servlet и javax.servlet/http), в пакетах javax.servlet.jsp и javax.servlet.jsp.target содержатся классы и интерфейсы, относящиеся к программированию Java Server Pages. Полное описание технологии Java Server Pages можно найти в спецификации по адресу (java.sun.com/products/jsp/download.htm

    Обзор технологии Java Server Pages

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

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

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

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

    Весь статический текст HTML, называемый в документации JSP шаблоном HTML (template HTML), сразу направляется в выходной поток. Выходной поток страницы буферизуется. Буферизацию обеспечивает класс JspWriter, расширяющий класс Writer. Размер буфера по умолчанию ограничен до 8 Кбайт, но его можно изменить атрибутом buffer тега . Наличие буфера позволяет заносить заголовки ответа в выходной поток совместно с выводимым текстом. В буфере заголовки будут размещены перед текстом.

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

    Архитектура JSP-страницы

    Базовая архитектура Java Server Pages в самом общем виде представлена на рисунке. Платформа J2EE обеспечивает базу, на которой функционирует все приложение в целом и страницы JSP, в частности, в то время, как сеть Интернет предоставляет механизм транспортировки данных.

    Стнаица JSP располагается на Web-сервере в среде виртуальной Java-машины. Доступ к страниц JSP, как и в случае сервлета, осуществляется через Web с использованием протокола HTTP.

    Страница JSP функционирует под управлением JSP Engine (среды исполнения JSP). Страница JSP может взаимодействовать с программным окружением с помощью компонентов JavaBeans, получая и устанавливая его параметры, используя теги: , , . Компонент JavaBean сам может участвовать в других процессах, предоставляя результаты в виде своих параметров, доступных страницам JSP, участвующим в сеасе, а через них — всем пользователям, запрашивающим эти страницы JSP.

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

    Основные модели архитектуры JSP

    Первая модель архитектуры JSP

    1. Запрос пользователя посылается через Web-браузер странице JSP.
    2. Страница JSP компилируется в сервлет (при первом обращении).
    3. Скомпилированный сервлет обращается к некоторому компоненту JavaBean, запрашивая у него информацию.
    4. Компонент JavaBean, в свою очередь, осуществляет доступ к информационным ресурсам (непосредственно или через компонент Enterprise JavaBeans).
    5. Полученная информация отображается в свойствах компонента JavaBeans, доступных странице JSP.
    6. Формируется ответ в виде страницы HTML с комбинированным содержанием (статическое, динамическое).

    Архитектура JSP Model 1 может с успехом применяться для небольших приложений. Однако использование данной модели для более сложных задач вызывает определенные трудности и не является технологичным из-за большого объема встроенных в страницу программных фрагментов. Для сложных корпоративных приложений рекомендуется применение второй модели архитектуры JSP.

    Вторая модель архитектуры JSP

    1. Запрос пользователя посылается через Web-браузер сервлету.
    2. Сервлет обрабатывает запрос, создает и инициализирует объект JavaBean или другие объекты, используемые страницей JSP, и запрашивает динамическое содержание у компонента JavaBean.
    3. Компонент JavaBean осуществляет доступ к информации непосредственно или через компонент Enterprise JavaBeans.
    4. Сервлет, направляющий запрос, вызывает сервлет, скомпилированный из страницы JSP.
    5. Сервлет, скомпилированный из страницы JSP, встраивает динамическое содержание в статический контекст HTML-страницы и отправляет ответ пользователю.

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

    Архитектуры JSP Model 2 в большей степени, чем архитектура JSP Model 1, соответствует идее отделения представления от содержания. Эта модель позволяет четко выделить отдельные части приложения и связанные с ними роли и обязанности персонала, занятого в разработке:

    • Дизайнер — разработка дизайна Web-страницы;
    • Разработчик — реализация функций управления и обработки.

    Чем сложнее разрабатываемая система, тем заметнее становятся преимущества архитектуры JSP Model 2.

    Функционирование JSP

    Технология JSP является технологией серверной стороны, поэтому все процессы обработки JSP протекают на стороне сервера. Страница JSP — текстовый документ, который в соответствии со спецификацией JSP, проходит две фазы:

    • фазу трансляции;
    • фазу выполнения.

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

    Жизненный цикл страницы JSP

    Трансляция и компиляция

    Когда страница оттранслирована и откомпилирована, сервлет страницы JSP в основном следует жизненному циклу сервлета, описанному в разделе Жизненный цикл сервлета :

    1. Если экземпляр сервлета страницы JSP не существует, контейнер:
      • загружает класс сервлета страницы JSP;
      • создает экземпляр класса сервлета;
      • инициализирует экземпляр сервлета вызовом метода jspInit.
    2. Вызывает метод _jspService, передавая ему объекты запроса и отклика.

    Если контейнеру нужно удалить сервлет страницы JSP, он вызывает метод jspDestroy.

    Выполнение


    При выполнении страницы JSP может возникать любое число исключений. Чтобы определить, что Web-контейнер должен передавать управление странице ошибки, если происходит исключение, необходимо определить в странице JSP следующую директиву page:

    Синтаксис JSP-страницы

    Страницы JSP, кроме HTML-тегов, содержат теги JSP следующих категорий:

    Директивы JSP

    Директивы всегда помещаются в начале JSP-страницы до всех остальных тегов, чтобы parser (анализатор) JSP при разборе текста в самом начале выделил глобальные инструкции. Таким, образом, JSP Engine (среда исполнения JSP), анализируя код, создает из JSP сервлет. Директивы представляют собой сообщения контейнеру JSP.

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

    Синтаксис задания директив на XML:

    Директива может иметь несколько атрибутов. В этом случае директива может быть повторена для каждого из атрибутов. В то же время пары «имяАтрибута=значение» могут располагаться под одной директивой с пробелом в качестве разделителя.

    Существует три типа директив:

    • page (страница)
    • taglib (библиотека тегов)
    • include (включить)

    Директива page

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

    Список возможных атрибутов директивы page представлен в таблице.

    Наименование атрибута Значение Описание
    language Строка Определяет язык, используемый в скриптлетах файла JSP, выражениях или любых включаемых файлах, в том числе, в теле оттранслированного кода. По умолчанию принимается значение «java»
    extends Строка Задает суперкласс для генерируемого сервлета. Этот атрибут следует использовать с большой осторожностью, поскольку возможно что сервер уже использует какой-нибудь суперкласс
    import Строка Определение импортируемых пакетов., например:
    Session true или false Значение true (принимается по умолчанию) свидетельствует о том, что заранее определенная переменная session (тип HttpSession) должна быть привязана к существующей сессии, если таковая имеется, в противном случае создается новая сессия, к которой осуществляется привязка. Значение false определяет что сессии не будут использоваться, и попытки обращения к переменной session приведут к возникновению ошибки при трансляции JSP страницы в сервлет
    Buffer none или размер буфера в кБ. Задает размер буфера для JspWriter out. Значение принимаемое по умолчанию зависит от настроек сервера, и не должно превышать 8 кБ. Если значение равно none вывод происходит непосредственно в объект
    autoFlush true или false Определяет, должен ли буфер освобождаться автоматически, когда он переполнен или произошла ошибка. По умолчанию значение true
    isThreadSafe true или false Значение true (принимается по умолчанию) задает нормальный режим выполнения сервлета, когда множественные запросы обрабатываются одновременно с использованием одного экземпляра сервлета, исходя из соображения, что автор синхронизировал доступ к переменным этого экземпляра. Значение false («ложь») сигнализирует о том, что сервлет должен наследовать SingleThreadModel (однопоточную модель), при которой последовательные или одновременные запросы обрабатываются отдельными экземплярами сервлета
    info Строка Определяет строку информации о странице JSP, которая будет доступна с помощью метода Servlet.getServletInfo ()
    errorPage Строка Значение атрибута представляет собой URL страницу, которая должна выводиться в случае возможных ошибок, вызывающих исключения
    isErrorPage true или false Сигнализирует о том, может ли эта страница использоваться для обработки ошибок для других JSP страниц. По умолчанию принимается значение false
    contentType Строка Определяет кодировку для страницы JSP и ответа, а также MIME-тип ответа JSP. Значение по умолчанию типа содержания — text/html, кодировки — ISO-8859-1. Например:
    contentType=»text/html;charset=ISO-8859-1″
    pageEncoding Строка Определяет кодировку символов страницы JSP. По умолчанию используется charset из атрибута contentType, если оно там определено. Если значение charset в атрибуте contentType не определено, значение pageEncoding устанавливается равным ISO-8859-1

    Директива taglib

    Директива taglib имеет следующий синтаксис:

    Префикс «имяПрефикса» используется при обращении к библиотеке. Пример использования библиотеки тегов mytags:

    В данном примере библиотека тегов имеет URI-адрес «http://www.taglib/mytags», в качестве префикса назначена строка customs, которая используется в странице JSP при обращении к элементам библиотеки тегов.

    Директива include

    Директива include имеет один атрибут — file. Она включает текст специфицированного ресурса в файл JSP. Эту директиву можно использовать для размещения стандартного заголовка об авторских правах на каждой странице JSP:

    Контейнер JSP получает доступ к включаемому файлу. Если включаемый файл изменился, контейнер может перекомпилировать страницу JSP. Директива include рассматривает ресурс, например, страницу JSP, как статический объект.

    Заданный URI обычно интерпретируется относительно JSP страницы, на которой расположена ссылка, но, как и при использовании любых других относительных URI, можно задать системе положение интересующего ресурса относительно домашнего каталога WEB-сервера добавлением в начало URI символа «/». Содержимое подключаемого файла обрабатывается как обычный текст JSP и поэтому может включать такие элементы, как статический HTML, элементы скриптов, директивы и действия.

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

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

    Объявления JSP

    Объявления располагаются в блоке объявлений, а вызываются в блоке выражений страницы JSP. Код в блоке объявлений обычно пишется на языке Java, однако серверы приложений могут использовать синтаксис и других скриптов. Объявления иногда используются для того, чтобы добавить дополнительную функциональность при работе с динамическими данными, получаемыми из свойств компонентов JavaBeans. Примеры объявлений представлены в таблице.

    Объявление глобальной целочисленной переменной i.
    Объявление и инициализация глобальной строковой переменной s.
    Объявление и инициализация глобальной целочисленной переменной n.
    Объявление метода adding сложения двух целочисленных значений,
    глобального для всей страницы JSP

    Объявление может содержать несколько строк, как например, в приведенном ниже коде вычисления значения функции fact (int n), которая должна быть равна 1 при n меньше 2 и n! при положительном значении n;

    Объявления не производят никакого вывода в стандартный выходной поток out. Переменные и методы, декларированные в объявлениях, инициализируются и становятся доступными для скриптлетов и других объявлений в момент инициализации страницы JSP.

    Скриптлеты JSP

    Эквивалентом синтаксиса скриптлета для XML является:

    Если в тексте скриптлета необходимо использовать последовательность символов %> именно как сочетание символов, а не как тег — признак окончания скриптлета, вместо последовательности %> следует использовать следующее сочетание символов %\>.

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

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

    Выражения JSP

    альтернативный синтаксис для выражений JSP при использовании XML:

    Порядок выполнения выражений в странице JSP слева-направо. Если выражение появляется более чем в одном атрибуте времени выполнения, то оно выполняется слева-направо в данном теге. Выражение должно быть полным выражением на определенном скрипте (как правило Java).

    Выражения выполняются во время работы протокола HTTP. Значение выражения преобразуется в строку и включается в соответствующую позицию файла JSP.

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

    Для того чтобы упростить выражения существует несколько заранее определенных переменных, которые можно использовать. Наиболее часто используемые переменные:

    • request, HttpServletRequest;
    • response, HttpServletResponse;
    • session, HttpSession — ассоциируется с запросом , если таковой имеется;
    • out, PrintWriter — буферизированный вариант типа JspWriter для отсылки данных клиенту.

    Комментарии JSP

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

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

    Действия JSP-страницы

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

    Согласно спецификации JSP, синтаксис действий базируется на XML. В таблице представлены соответствия утверждений JSP и XML.

    Конструкция JSP Эквивалентная конструкция в XML
    . . .
    . . .
    . . .

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

    Список стандартных действий

    Тип действия Назначение действия
    Объявление объекта JavaBean, который будет использоваться на странице JSP
    Установление значения свойства объекта JavaBean
    Чтение значения свойства объекта JavaBean
    Включение в страницу JSP дополнительных статических и динамических ресурсов
    Перенаправление обработки на другой статический ресурс, например сервлет
    Подключение дополнительных программных модулей (компонент JavaBean или апплет)
    Определение значения параметра

    Атрибуты тега действия

    По умолчанию все атрибуты имеют семантику page — фиксированное значение времени транслирования. Большинство атрибутов стандартных действий относятся к типу значений времени трансляции. К значениям, вычисляемым в процессе запроса, относятся атрибуты, представленные в таблице.

    Наименование атрибута Наименование действия Примечание
    beanName jsp:useBean Поиск или создание нового экземпляра JavaBean
    height jsp:plugin Определение высоты объекта, размещаемого на странице JSP
    width jsp:plugin Определение ширины объекта, размещаемого на странице JSP
    bean | applet jsp:plugin Генерирование кода (в зависимости от типа используемого броузера), который создает тэг OBJECT или EMBED для Java plugin
    page jsp:include Подключение файла в момент запроса страницы
    page jsp:forward Перенаправление запроса на другую страницу
    value jsp:setProperty Установка свойств компонента JavaBean
    value jsp:getProperty Чтение свойств компонента JavaBean в выходной поток
    value jsp:param Определение значения параметры для компонента, размещаемого на странице JSP

    Действие

    • id — идентификатор экземпляра класса внутри страницы JSP;
    • scope — область видимости (page, request, session, application).

    Если объект с данными атрибутами id, scope не найден, предпринимается попытка создать объект, используя значения, определенные в его атрибутах. Синтаксис действия может включать тело :

    При наличии в объявление тела, оно будет вызвано на выполнение, если компонент JavaBean, к которому обращено действие, уже существует. Содержимое тела действия строго не ограничено, однако, как правило, тело действия содержит скриптлеты или теги , модифицирующие свойства созданного объекта.

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

    • найти существующий компонент JavaBean. Если объект найден, то он доступен, например, из объекта ServletRequest, определенного для страницы с помощью метода getAttribute(name);
    • создать новый экземпляр класса JavaBean — создается новая переменная на языке скрипта с именем, определяемым параметром id, и в области видимости, заданной параметром scope;
    • используя атрибут type, задать локальное имя объекту, определенном в другой странице JSP или сервлете (атрибуты class или beanName при этом не используются).

    Тег имеет параметры, представленные в таблице.

    Атрибут Описание атрибута
    id Параметр, идентифицирующий экземпляр объекта в пространстве имен, специфицированном в атрибуте scope. Это имя используется для ссылки на компонент JavaBean из страницы JSP.
    scope Атрибут, определяющий область видимости ссылки на экземпляр объекта JavaBean. Допустимыми значениями являются page, request, session, application. Данный атрибут фактически описывает пространство имен и цикл жизни ссылки на объект. По умолчанию значение объекта равно page.

    page (страница). Объект, определенный с областью видимости page, доступен до тех пор, пока не будет отправлен ответ клиенту или пока запрос к текущей странице JSP не будет перенаправлен куда-нибудь еще. Ссылки на объект возможны только в пределах страницы, в которой этот объект определен. Объекты, объявленные с атрибутом page, сохраняются в объекте pageContext.
    request (запрос). Объект, имеющий область видимости request, существует и доступен в течение текущего запроса, и остается видимым, даже если запрос перенаправляется другому ресурсу в том же самом цикле выполнения. Объекты, декларированные с атрибутом области видимости request, сохраняются в объекте request.
    session (сессия). Объект, имеющий область видимости session доступен в течение текущего сеанса, если страница JSP «знает» о сеансе.
    application (приложение). Объект, имеющий область видимости application доступен страницам, обрабатывающим запросы в одном и том же приложении Web, и cуществует до тех пор, пока сервер приложений поддерживает объект ServletContext. Объекты, объявленные с атрибутом области видимости application, сохраняются в объекте application.

    class Параметр, определяющий полное имя класса реализации объекта. Данный атрибут используется при инициализации экземпляра компонента JavaBean, если он еще не существует в данной области видимости scope.
    beanName Наименование класса реализации объекта. Данный параметр используется, если компонент JavaBean еще не существует. Параметр beanName должен удовлетворять правилам наименования переменных, предусмотренным спецификацией языка скриптлетов. Формат параметра : «строка1.строка2.строка3» — для классов и «строка1/строка2/строка3» — для ресурсов. Параметр beanName предполагает использование метода instantiate () класса java.beans.Beans.
    type Атрибут type, определяющий тип специфицированного объекта, дает возможность определить тип переменных скрипта как класс, суперкласс или интерфейс, реализуемый классом. С помощью атрибута type можно избежать автоматической инициализации компонента JavaBean, если он еще не существует в данной области видимости. По умолчанию атрибут type имеет значение, определенное в атрибуте class. Если объект не соответствует задаваемому атрибутом type типу, может быть возбуждено исключение java.lang.ClassCastException.

    Если имя класса (class) и имя объекта (beanName) не определены, объект должен быть представлен в заданной области видимости. Значение идентификатора id должно быть уникально в текущем модуле трансляции (JSP-странице), иначе возникает ошибка трансляции.

    Действие

    Тег имеет ряд атрибутов, которые представлены в таблице. При записи тега допускается использовать не все возможные атрибуты.

    Атрибут Описание атрибута
    name Параметр, идентифицирующий экземпляр объекта JavaBean, предварительно определенный в теге , свойство которого устанавливаются текущим тегом
    property Имя свойства, которому необходимо определить значение. Если используется символ «*», то предполагается автоматическая установка значений свойств. В последнем случае соответствующие элементы формы должны иметь имена, совпадающие с именами устанавливаемых свойств компонента JavaBean. В этом случае по именам элементов формы осуществляется поиск (look up) соответствующих свойств компонента JavaBean с последующей установкой их значений
    param Имя параметра запроса, который передается свойству компонента JavaBean. Параметры запроса, как правило, ссылаются на соответствующие элементы HTML-страницы. Этот атрибут не может использоваться одновременно с атрибутом value
    value Новое значение устанавливаемого свойства

    Значения свойств компонента JavaBean устанавливается с учетом соответствия типов значения и свойства. Тег позволяет устанавливать значения как простых, так и индексированных ствойств. Свойства компонента JavaBean имеют определенный тип, а также методы setter и getter. При установке параметров обычно проверяются наличия свойств компонента JavaBean, их имена и типы, являются ли свойства простыми или индексированными и т.д.

    Значения одного или нескольких свойств компонента JavaBean могут быть установлены несколькими способами:

    • с помощью параметров объектов типа request (запрос);
    • с использованием строковой константы;
    • с помощью выражения, вычисляемого во время запроса.

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

    Листинг примера использования тега

    Действие

    Тег имеет ряд атрибутов, которые представлены в таблице. При записи тега допускается использовать не все возможные атрибуты.

    Атрибут Описание атрибута
    name Параметр, идентифицирующий экземпляр объекта JavaBean, предварительно определенный в теге
    property Имя свойства, значение которого необходимо получить

    Значения атрибутов в тегах и ссылаются на объект, который получается из объекта pageContext с помощью метода findAttribute ().

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

    Листинг примера использования тега

    Действие

    Тег имеет ряд атрибутов, которые представлены в таблице. При записи тега допускается использовать не все возможные атрибуты.

    Атрибут Описание атрибута
    name Параметр, идентифицирующий экземпляр объекта JavaBean, предварительно определенный в теге
    property Имя свойства, значение которого необходимо получить

    Значения атрибутов в тегах и ссылаются на объект, который получается из объекта pageContext с помощью метода findAttribute ().

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


    Действие

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

    Действие имеет следующий синтаксис:

    Примером может быть включение страницы-приветствия:

    Тег имеет атрибуты, представленные в таблице.

    Атрибут Описание атрибута
    page Атрибут page определяется относительно текущей страницы JSP. Включаемая страница имеет доступ только к объекту JspWriter и не может устанавливать заголовки
    flush Необязательный атрибут flush управляет переполнением. Если этот атрибут имеет значение true и выходной поток страницы JSP буферизуется, то буфер освобождается при переполнении, в противном случае — не освобождается. По умолчанию значение атрибута flush равно false

    Действие может включать элементы , которые предоставляют значения для некоторых параметров запроса, используемые для включения.

    Действие

    Смысл атрибутов page и flush тот же, что и в случае тега .

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

    Действие

    Атрибуты действия , представленные в таблице, обеспечивают конфигурационные данные для предоставления соответствующего элемента.

    Атрибут Описание атрибута
    type Определение типа объекта : компонент JavaBean или апплет
    code Код объекта в соответствии со спецификацией HTML
    codebase Расположение объекта в соответствии со спецификацией HTML
    align Выравнивание объекта в соответствии со спецификацией HTML
    archive Список архивов в соответствии со спецификацией HTML
    height Размер объекта по высоте в соответствии со спецификацией HTML
    hspace Горизонтальный отступ объекта в соответствии со спецификацией HTML
    jreversion Идентифицирует номер версии спецификации JRE (по умолчанию — «1.2»)
    name Наименование компонента в соответствии со спецификацией HTML
    hspace Вертикальный отступ в соответствии со спецификацией HTML
    width Размер объекта по ширине в соответствии со спецификацией HTML
    nspluginurl URL-адрес для браузера Netscape Namvigator, откуда может быть загружен образец
    iepluginurl URL-адрес для браузера Internet Explorer, откуда может быть загружен образец

    Элементы определяют параметры апплета или комопнента JavaBean, элементы — некоторое содержание, используемое браузером клиента в том случае, если дополнительный модуль по какой-либо причине не может быть вызван, если OBJECT / EMBED не поддерживаются браузером клиента или при возникновении других проблем. Действие , как и , является «дочерним» действием тега и вне тега не применяется.

    Коды загружаемых образцов могут не поставляться вместе с контейнером JSP поставщика, вместо реального кода могут использоваться ссылки на стандартные образцы фирмы «Sun Microsystems».

    Действие

    Действие имеет следующий синтасис:

    Пример использования тега для определения значения параметра апплета:

    Неявные объекты

    Наименование объекта Тип объекта Назначение
    request (запрос) javax.servlet.HttpServletRequest Запрос, требующий обслуживания. Область видимости — запрос. Основные методы : getAttribute, getParameter, getParameterNames, getParameterValues
    Таким образом, запрос request обеспечивает обращение к параметрам запроса через метод getParameter, типу запроса (GET, POST, HEAD, и т.д.), и входящим HTTP заголовкам (cookies, Referer, и т.д.).
    response (ответ) javax.servlet.HttpServletResponse Ответ на запрос. Область видимости — страница. Поскольку поток вывода (см. out далее) буферизован, можно изменять коды состояния HTTP и заголовки ответов, даже если это недопустимо в обычном сервлете, но лишь в том случае, если какие-то данные вывода уже были отправлены клиенту.
    out (вывод) javax.servlet.jsp.JspWriter Объект, который пишет в выходной поток. Область видимости — страница. Основные методы : clear, clearBuffer, flush, getBufferSize, getRemaining.
    Необходимо помнить, размер буфера можно изменять и даже отключить буферизацию, изменяя значение атрибута buffer директивы page. Также необходимо обратить внимание, что out используется практически исключительно скриплетами, поскольку выражения JSP автоматически помещаются в поток вывода, что избавляет от необходимости явного обращения к out.
    pageContext (содержание страницы) javax.servlet.jsp.pageContext Содержимое JSP-страницы. Область видимости — страница. pageContext поддерживает доступ к полезным объектам и методам, обеспечивающим явный доступ реализации JSP к специфическим объектам. Основные методы : getSession, getPage, findAttribute, getAttribute, getAttributeScope, getAttributeNamesInScope, getException.
    session (сеанс) javax.servlet.HttpSession Объект типа Session, создаваемый для клиента, приславшего запрос. Область видимости — страница. Основные методы getId, getValue, getValueNames, putValue.
    Сессии создаются автоматически, и переменная session существует даже если нет ссылок на входящие сессии. Единственным исключением является ситуация, когда разработчик отключает использование сессий, используя атрибут session директивы page. В этом случае ссылки на переменную session приводят к возникновению ошибок при трансляции JSP страницы в сервлет.
    application (приложение) javax.servlet.ServletContext Контекст сервлета, полученный из объекта конфигурации сервлета при вызове методов : getServletConfig или getContext. Область видимости — приложение. Основные методы : getMimeType, getRealPath.
    config (конфигурация) javax.servlet.ServletConfig Объект ServletConfig текущей страницы JSP. Область видимости — страница. Основные методы : getInitParameter, getInitParameterNames
    page (страница) java.lang.Object Экземпляр класса реализации текущей страницы JSP, обрабатывающий запрос. Область видимости — страница. Объект доступен, но, как правило, используется редко. По сути является синонимом для this, и не нужен при работе с Java.
    exception (исключение) java.lang.Throwable Объект Throwable, выводимый в страницу ошибок error page. Область видимости — страница. Основные методы : printStackTrace, toString, getMessage, getLocalizedMessage.

    Компонент JavaBean

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

    Компоненты JavaBean – это одноуровневые объекты, использующиеся для того, чтобы инкапсулировать в одном объекте сложный код, данные или и то и другое. Компонент JavaBean может иметь свойства, методы и события, открытые для удаленного доступа.

    Компонент JavaBean – это java-класс, удовлетворяющий определенным соглашениям о наименовании методов и экспортируемых событий. Одним из важных понятий технологии JavaBeans является внешний интерфейс properties (свойства). Property – это пара методов (getter и setter), обеспечивающих доступ к информации о внутреннем состоянии компонента JavaBean.

    Для обращения к компонентам JavaBeans на странице JSP необходимо использовать следующее описание тега в разделе head :

    Bean , т.е. текущая страница JSP.

    Обязательный атрибут класса компонента «class» может быть описан следующим способом:

    Свойство компонента JavaBean с именем myBean устанавливается тегом:

    Для чтения свойства компонента JavaBean с именем myBean используется тег:

    В следующем листинге приведен пример компонента JavaBean, содержащего строку mystr, используемую в качестве свойств.

    Листинг компонента JavaBean

    Теги JSP

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

    Существенным преимуществом использования библиотеки тегов перед компонентами JavaBean заключается в том, что тег (java-класс) имеет доступ к странице JSP и может оперировать содержимым самой страницы JSP.

    Для использования/создания библиотеки тегов необходимо разработать:

    • класс (Tag handler class), обрабатывающий тег и определяющий его функциональные свойства;
    • XML-файл – дескриптор библиотеки тегов Tag Library Descriptor (файл TLD) – связывающий наименование элементов описания тегов с их реализацией.

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

    1. Зарегистрировать в дескрипторе поставки web.xml с помощью директивы описание месторасположения библиотеки тегов.
      Пример описания библиотеки тегов templates.tld в дескрипторе поставки web.xml:

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

      На странице JSP с помощью директивы необходимо указать месторасположение файла TLD.
      Пример описания библиотеки тегов templates.tld на странице JSP:

    В данных примерах библиотека тегов templates.tld располагается в директории WEB-INF/tlds. При компиляции страницы JSP в сервлет пользовательские теги преобразуются в действия над объектами серверной стороны. Интерфейсы и классы, с помощью которых создаются пользовательские теги, располагаются в пакете javax.servlet.jsp.tagext.

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

    • открывающий тег – действие, выполняемое java-классом при открытии тега;
    • тело действия;
    • закрывающий тег – действие, выполняемое java-классом при закрытии тега.

    Java-класс, обрабатывающий тег, может реализовывать один из следующих интерфейсов:

    • Tag;
    • IterationTag;
    • BodyTag.

    Интерфейс Tag

    Интерфейс IterationTag

    Интерфейс BodyTag

    Использование тегов с атрибутами

    Пример простейшего тега приведен в следующем листинге.

    Исходный код необходимо откомпилировать обычным образом и установить в контейнер так же, как устанавливается сервлет. Необходимо контролировать соответствие пакетов Java и каталогов файловой системы : в каталоге WEB-INF/classes данный тег InfoTag.class должен быть установлен в подкаталог tags/sdo.

    Пример JSP-страницы

    Результатом выполнения данной JSP-страницы будет сформированный HTML-документ с приветствием и текущей датой.

    Перевод руководства по JavaServer Pages JSP 1.2

    Версия: 1.2

    Пожалуйста, направляйте комментарии по e-mail: jsp-spec-comments@eng.sun.com

    Понедельник, 27 августа, 2001 г.
    Редактор: Eduardo Pelegrí-Llopart.

    901 San Antonio Road
    Palo Alto, CA 94303 USA
    650 960-1300 факс: 650 969-9131

    Релиз: 17 сентября 2001 г.

    Copyright 2001 Sun Microsystems, Inc.
    901 San Antonio Road, Palo Alto, California 94303, U.S.A.
    Все Права Зарезервированы.

    ЛИЦЕНЗИЯ

    Данная Спецификация защищена авторскими правами, и информация, приведённая здесь, может быть защищена одним или более патентами США, иностранными патентами или задействованными приложениями.

    За исключением случаев, указанных в данной лицензии, никакая часть данной Спецификации не может воспроизводиться в любой форме и любым способом без наличия предварительного письменной авторизации Sun Microsystems, Inc. («Sun») и её лицензоров, если имеются.

    Любая часть данной Спецификации и описанной здесь информации управляется терминами и условиями данной лицензии и Export Control Guidelines, как установлено ранее в Terms of Use на сайте Sun.

    Просматривая, загружая и копируя данную Спецификацию, Вы соглашаетесь с тем, что Вы прочли, поняли и согласны со всеми терминами и условиями, установленными здесь и далее.

    Настоящим документом Sun предоставляет Вам лицензию на бесплатное, неисключительное пользование без права передачи (без права на сублицензию), с сохранением прав интеллектуальной собственности Sun, что является непременным условием использования данной Спецификации для внутренних целей дизайна и разработки Ваших Java-аплетов и приложений, предназначенных для работы на платформе Java, или для создания чисто рабочих реализаций данной Спецификации, которые:

    (i) полную реализацию текущей версии Спецификации без подразделения или объединения её;
    (ii) реализует весь интерфейс и функциональность данной Спецификации без подразделения или объединения её;
    (iii) включают полную реализацию всех необязательных компонентов (как определено Спецификацией), которые Вы выбрали для реализации, без подразделения или объединения;
    (iv) реализует все интерфейсы и функциональность таких необязательных компонентов без подразделения или объединения;
    (v) не добавляют никаких дополнительных пакетов, классов или интерфейсов к пакетам «java.*» или «javax.*» или подпакетам или другим пакетам, определённым в данной Спецификации;
    (vi) удовлетворяют всем требованиям тестирования, доступным от Sun, относящимся к самой последней версии данной Спецификации, опубликованной за шесть (6) месяцев до любого релиза реализации такой чисто рабочей реализации или обновления до неё;
    (vii) не происходят от какого-либо кода-источника Sun или кодов двоичных материалов; и
    (viii) не включает какого-либо первичного кода Sun или кодов двоичных материалов без отдельной соответствующей лицензии Sun. Данная Спецификация содержит информацию о правах собственности Sun и может использоваться только в соответствии с данной лицензией.

    Действие данной лицензии оканчивается немедленно без предупреждения от Sun, если Вы не согласны с каким-либо из условий данной лицензии. После окончания или истечения срока действия данной лицензии Вы обязаны исключить использование или уничтожить имеющуюся у Вас Спецификацию.

    ТОРГОВЫЕ МАРКИ

    Никакие права названия или интересы торговых марок, сервисных марок или торговых имён Sun или лицензоров Sun не передаются по данному соглашению.

    Sun, Sun Microsystems, логотип Sun, Java, логотип Java Coffee Cup, JSP и JavaServer Pages являются торговыми марками или зарегистрированными торговыми марками Sun Microsystems, Inc. в США и других странах.

    ОГРАНИЧЕННАЯ ГАРАНТИЯ

    ДАННАЯ СПЕЦИФИКАЦИЯ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ». SUN НЕ ДА╗Т НИКАКИХ ГАРАНТИЙ, ЯВНЫХ ИЛИ КОСВЕННЫХ (ВКЛЮЧАЯ — НО НЕ ОГРАНИЧИВАЯСЬ ИМИ — ГАРАНТИИ РЕАЛИЗУЕМОСТИ), СООТВЕТСТВИЯ ОПРЕДЕЛ╗ННОМУ НАЗНАЧЕНИЮ ИЛИ НЕНАРУШЕНИЯ УСЛОВИЙ, ЧТО СОДЕРЖИМОЕ ДАННОЙ СПЕЦИФИКАЦИИ ПОДХОДИТ ДЛЯ КАКИХ-ЛИБО ЦЕЛЕЙ ИЛИ ЧТО ЛЮБОЕ ИСПОЛЬЗОВАНИЕ ИЛИ РЕАЛИЗАЦИЯ ТАКОГО СОДЕРЖИМОГО НЕ БУДЕТ НАРУШАТЬ КАКИХ-ЛИБО ПАТЕНТОВ ТРЕТЬЕЙ СТОРОНЫ, АВТОРСКИХ ПРАВ, КОММЕРЧЕСКОЙ ТАЙНЫ ИЛИ ИНЫХ ПРАВ.

    Данный документ не содержит каких-либо обязательств на реализацию или выпуск какой-либо части данной Спецификации в каком-либо продукте.

    ДАННАЯ СПЕЦИФИКАЦИЯ МОЖЕТ СОДЕРЖАТЬ ТЕХНИЧЕСКИЕ НЕТОЧНОСТИ ИЛИ ТИПОГРАФСКИЕ ОШИБКИ. ИЗМЕНЕНИЯ ПЕРИОДИЧЕСКИ ДОБАВЛЯЮТСЯ К ИМЕЮЩЕЙСЯ ИНФОРМАЦИИ; ЭТИ ИЗМЕНЕНИЯ БУДУТ ВНЕДРЕНЫ В НОВЫЕ ВЕРСИИ ДАННОЙ СПЕЦИФИКАЦИИ, ЕСЛИ ОНИ (ВЕРСИИ) ПОЯВЯТСЯ. SUN МОЖЕТ В ЛЮБОЕ ВРЕМЯ ДЕЛАТЬ УЛУЧШЕНИЯ И/ИЛИ ВНОСИТЬ ИЗМЕНЕНИЯ В ПРОДУКТЫ И/ИЛИ ПРОГРАММЫ, ОПИСАННЫЕ В ДАННОЙ СПЕЦИФИКАЦИИ.

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

    ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ

    В ДОПОЛНЕНИЕ К НЕ ЗАПРЕЩ╗ННОМУ ЗАКОНОМ, НИ ПРИ КАКИХ СОБЫТИЯХ SUN ИЛИ Е╗ ЛИЦЕНЗОРЫ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБОЙ УЩЕРБ, ВКЛЮЧАЯ, БЕЗ ОГРАНИЧЕНИЯ, УПУЩЕННУЮ ВЫГОДУ, ПОТЕРЮ ДАННЫХ ИЛИ ЗА ПРИЧИН╗ННЫЙ, КОСВЕННЫЙ, ПОСЛЕДУЮЩИЙ, СЛУЧАЙНЫЙ ИЛИ УМЫШЛЕННЫЙ ВРЕД, НАНЕС╗ННЫЙ КАКИМ-ЛИБО ОБРАЗОМ, ВНЕ ЗАВИСИМОСТИ ОТ ПРАВИЛ ОБ ОТВЕТСТВЕННОСТИ, ПРИЧИН╗ННЫЙ ИЛИ ОТНОСЯЩИЙСЯ К: ЛЮБОМУ ОБОРУДОВАНИЮ, ИСПОЛЬЗОВАНИЮ, МОДИФИЦИРОВАНИЮ ИЛИ ИНОМУ ИСПОЛЬЗОВАНИЮ ДАННОЙ СПЕЦИФИКАЦИИ, ДАЖЕ ЕСЛИ SUN И/ИЛИ Е╗ ЛИЦЕНЗОРЫ БЫЛИ УВЕДОМЛЕНЫ О ВОЗМОЖНОСТИ ТАКОГО УЩЕРБА/ВРЕДА.

    Вы страхуете и защищаете Sun и её лицензоров от любых претензий, являющихся результатом:

    (i) Вашего использования данной Спецификации;
    (ii) использования или распространения Ваших Java-приложений, аплетов и/или чисто рабочих реализаций; и/или
    (iii) любых претензий, которые могут явиться результатом несовместимости последующих версий или релизов любой Спецификации, использованной Вами, со Спецификацией, предоставленной Вам по данному соглашению.

    ОГРАНИЧЕННЫЕ ПРАВА

    Правительство США: Если данная Спецификация получена от имени или для Правительства США первичным контрактором или субконтрактором Правительства США (любого уровня), тогда права Правительства в области Программного Обеспечения и сопутствующей документации будут действовать так, как описано ранее в данной лицензии; это действует в соответствии с правилами от 48 C.F.R. 227.7201 до 227.7202-4 (для приобретений Департамента Обороны/Department of Defense (DoD)) и в соответствии с правилами 48 C.F.R. 2.101 и 12.212 (для приобретений не Департамента Обороны).

    КУДА СООБЩИТЬ

    Вы можете сообщить о какой-либо неоднозначности, неполноте или неточностях в связи с использованием Вами данной Спецификации («Обратная Связь/Feedback»). В связи с тем, что Вы направляете Sun информацию Feedback, Вы, кроме того:

    (i) согласны с тем, что эта информация предоставляется Вами на некоммерческой и неконфиденциальной основе, и
    (ii) предоставляете Sun бессрочное, неисключительное, всемирно действующее, неотзываемое разрешение безвозмездно, с правом сублицензирования на несколько уровней сублицензирования, внедрять, публиковать и использовать без ограничений Feedback для любых целей, относящихся к данной Спецификации и её последующим версиям, реализациям, и утилитам тестирования.

    Статус

    Это спецификация JSP 1.2, разработанная группой экспертов JSR053 как часть процесса Java Community Process (детали — по адресу http://jcp.org/jsr/detail/53.jsp).

    JSP.S.1 Процессы Сообщества Java

    JCP создаёт спецификации, используя три сообщества: сообщество экспертов (the expert group), participants\участники JCP и public\публика вообще.

    Эксперты является авторами спецификаций, создавая проекты/drafts.

    Проекты
    проходят путь от экспертов, через участников, к публике, постепенно совершенствуясь в деталях, всегда возвращая комментарии обратно группе экспертов; final draft/окончательный проект отправляется для одобрения в Executive Committee\Исполнительный Комитет.

    Лидер группы экспертов отвечает за облегчение работы группы экспертов, авторизацию спецификации и за организацию reference implementation\справочной реализации и conformance test suite\блока тестирования на соответствие.

    JSP.S.2 JCP и Эта Спецификация


    JCP разработан как чрезвычайно гибкий процесс, так что каждая группа экспертов может адресовать требования специфического сообщества, обслуживаемого ею. Справочная реализация JSP 1.2 и Servlet 2.3 использует код, который разрабатывается как открытый проект-ресурс по соглашению с Apache Software Foundation.

    Данная спецификация содержит главы, которые получены непосредственно из комментариев javadoc в классах API, но там, где имеются расхождения, данная спецификация имеет преимущество над комментариями javadoc.

    Процесс JCP предоставляет механизм обновления спецификации в процессе поддержки через Erratas\Списки Ошибок. Если они имеются, эти списки имеют приоритет над данной спецификацией.

    Приложения C и D являются нормативными; остальные приложения являются ненормативными.

    Предисловие

    Этот документ является спецификацией JavaServer Pages тм 1.2 (JSP 1.2).

    Данная Спецификация была разработана как часть процесса Java Community Process (JCP). Комментарии от Экспертов, Участников и Публики были рассмотрены, и все изменения были внесены в спецификацию, где это было необходимо.

    JSP.P.1 Сравнение с JSP 1.1

    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.P.2 Лицензирование Спецификации

    Детали условий, по которым данный документ распространяется, даны в лицензии.

    JSP.P.3 Для кого предназначен этот документ

    Этот документ является авторизованной спецификацией JSP 1.2. Он предназначен для предоставления требований к реализациям процессинга JSP и поддерживается web-контейнерами в web-серверах и серверами приложений.
    Он не является справочником пользователя. Мы ожидаем появления других документов, предназначенных для различных категорий читателей.

    JSP.P.4 Родственные Документы

    Разработчики контейнеров JSP и авторы страниц JSP могут найти необходимую информацию также в следующих документах:

    Таблица JSP.P-1 Некоторые Родственные Web-Сайты

    Понятие же «физического вакуума» в релятивистской квантовой теории поля подразумевает, что во-первых, он не имеет физической природы, в нем лишь виртуальные частицы у которых нет физической системы отсчета, это «фантомы», во-вторых, «физический вакуум» — это наинизшее состояние поля, «нуль-точка», что противоречит реальным фактам, так как, на самом деле, вся энергия материи содержится в эфире и нет иной энергии и иного носителя полей и вещества кроме самого эфира.

    В отличие от лукавого понятия «физический вакуум», как бы совместимого с релятивизмом, понятие «эфир» подразумевает наличие базового уровня всей физической материи, имеющего как собственную систему отсчета (обнаруживаемую экспериментально, например, через фоновое космичекое излучение, — тепловое излучение самого эфира), так и являющимся носителем 100% энергии вселенной, а не «нуль-точкой» или «остаточными», «нулевыми колебаниями пространства». Подробнее читайте в FAQ по эфирной физике.

    В чем разница между JSF, Servlet и JSP? Введение в сетевое программирование

    Оставьте комментарий 6,950

    JavaServer Pages (JSP) — это стандартное расширение Java, которое определено поверх сервлетных расширений. Цель JSP состоит в упрощении создания и управления динамическими Web страницами.

    Как упоминалось ранее, свободно распространяемый Tomcat, реализация от jakarta.apache.org, автоматически поддерживает JSP.

    JSP позволяет вам комбинировать HTML Web страницы с кусочками кода Java в одном документе. Java код обрамляется специальными тегами, которые говорят JSP контейнеру, что он должен использовать код для генерации единого документа или его части. Выгода JSP состоит втом, что вы можете содержать единый документ, которые представляет и страницу, и Java код, который в нее включен. Недостаток состоит в том, что тот, кто поддерживает работоспособность JSP страницы, должен иметь опыт и HTML, и в Java (однако, со временем ожидается появление визуальных построителей JSP страницы).

    При первой загрузке JSP загружается JSP контейнером (который обычно ассоциирован, или является частью Web сервера), далее сервлетный код, который обязательно выделяется JSP тегами, автоматически генерируется, компилируется и загружается в контейнер сервлетов. Статическая часть HTML страницы производится посредством посылки статического объекта типа String в метод write(). Динамическая часть включается прямо в сервлет.

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

    Структура JSP страницы — это что-то среднее между сервлетом и HTML страницей. JSP тэги начинаются и заканчиваются угловой скобкой, также как и HTML коды, но теги также включают знаки процента, так что все JSP теги обозначаются так:

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

    Вот чрезвычайно простой JSP пример, который использует стандартный библиотечный Java вызов для получения текущего времени в миллисекундах, которое затем делится на 1000, чтобы получить время в секундах. Так как используется JSP выражение ( The time in seconds is : ///:

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

    Когда клиент создает запрос к JSP странице, Web сервер должен быть сконфигурирован, чтобы переправить запрос к JSP контейнеру, который затем вовлекает страницу. Как упомянуто ранее, при первом обращении запрашивается страница, генерируются компоненты, указанные на странице, и JSP контейнером компилируется один или несколько сервлетов. В приведенном выше примере сервлет будет содержать код конфигурации объекта HTTPServletResponse, производя объект PrintWriter»а (который всегда называется out), а затем включится расчет времени с помощью очень краткой инструкции, но среднестатистический HTML программист/Web дизайнер не имеет опыта в написании такого кода.

    Неявные объекты

    Сервлеты включают классы, которые предоставляют удобные утилиты, такие как HttpServletRequest, HttpServletResponse, Session и т. п. Объекты этих классов встроены в JSP спецификацию и автоматически доступны для использования в вашем JSP без написания дополнительных строк кода. Неявные объекты JSP детально перечислены в приведенной ниже таблице.

    Тип (javax.servlet) Область видимости
    request Зависимый от протокола подтип HttpServletRequest Запрос, который совершил вызов службы. request
    response Зависимый от протокола подтип HttpServletResponse Ответ на запрос. page
    pageContext jsp.PageContext Контекст страницы, инкапсулирующий зависящие от реализации возможности и предоставляющий удобные методы и доступ к пространству имен этого JSP. page
    session Зависящий от протокола подтип http.HttpSession Объект сессии, создаваемый для запроса клиента. Смотрите объект Session для сервлета. session
    application ServletContext Контекст сервлета, получаемый из объекта конфигурации сервлета (например, getServletConfig(), getContext(). app
    out jsp.JspWriter Объект, который пишет в выходной поток. page
    config ServletConfig ServletConfig для этого JSP. page
    page java.lang.Object Экземпляр класса реализации этой страницы, обрабатывающий текущий запрос. page

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

    JSP директивы

    Директивы являются сообщениями JSP контейнеру и обозначаются символом «@»:

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

    сообщает, что скриптовой язык, используемый внутри JSP страницы, это Java. Фактически, JSP спецификация только описывает семантику скриптов для языковых атрибутов, эквивалентных «Java». Смысл этой директивы состоит во встраивании гибкости в JSP технологию. В будущем, если вы выберите другой язык, скажем Python (хороший выбор для скриптов), то такой язык должен иметь поддержку Java Run-time Environment, выставляя наружу объектную модель Java технологии для скриптового окружения, особенно для неявных переменных, определенных выше, свойств JavaBeans и публичных методов.

    Наиболее важными директивами являются директивы страницы. Они определяют несколько атрибутов страницы и взаимодействие этих атрибутов с JSP контейнером. Эти атрибуты включают: language, extends, import, session, buffer, autoFlush, isThreadSafe, info и errorPage. Например:

    Эта строка, прежде всего, указывает, что эта страница требует участие в HTTP сессии. Так как мы не установили директиву языка, JSP контейнер по умолчанию использует Java и неявную переменную скриптового языка с названием session типа javax.servlet.http.HttpSession. Если бы директива использовала false, то неявная переменная session будет недоступна. Если переменная session не определена, то по умолчанию считается «true».

    Атрибут import описывает типы, которые доступны для скриптовой среды. Этот атрибут используется так же, как и в языке программирования Java, т. е., разделенный запятыми обычный список выражений import. Этот список импортируется транслируемой реализацией JSP страницы и доступен для скриптового окружения. Скажем еще раз, что в настоящее время это определено, только если значением директивы языка является «java».

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

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

    Пробелы после » » не обязательны.

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

    declaration scriptlet expression

    Первая форма позволяет вам добавлять комментарии в исходный код JSP, которые ни в какой форме не появятся в HTML странице, посылаемой клиенту. Конечно, вторая форма комментариев не специфична для JSP — это обычный HTML комментарий. Интересно то, что вы можете вставлять JSP код внутрь HTML комментария и результат будет показан в результирующей странице.

    Декларации используются для объявления переменных и методов в скриптовом языке (в настоящее время только в Java), используемых на JSP странице. Декларация должна быть законченным Java выражением и не может производить никакого вывода в выходной поток. В приведенном ниже примере Hello.jsp декларации для переменных loadTime, loadDate и hitCount являются законченными Java выражениями, которые объявляют и инициализируют новые переменные.

    //:! c15:jsp:Hello.jsp Этот JSP комментарий не появится в сгенерированном html — %> Это JSP директива: — %> Эта декларации: — %> Следующие несколько строк являются результатом JSP выражений, вставленных в сгенерированный html; знак «=» указывает на JSP выражение — %>

    Эта страница была загружена

    Hello, world! It»s

    Here»s an object:


    This page has been up seconds


    Page has been accessed times since

    Когда вы запустите эту программу, вы увидите, что переменные loadTime, loadDate и hitCount содержат свои значения между обращениями к странице, так что они явно являются полями, а не локальными переменными.

    В конце примера помещен скриплет, который пишет «Goodbye» на консоль Web сервера и «Cheerio» в неявный объект вывода JspWriter. Скриплет может содержать любые фрагменты кода, которые являются имеющими силу инструкциями Java. Скриплеты выполняются во время обработки запроса. Когда все фрагменты скриплета в данном JSP будут скомбинированы по порядку своего появления в JSP странице, они должны дать имеющую силу инструкцию, определенную для языка программирования Java. Будет ли скриплет производить вывод в выходной поток или нет, зависит только от кода скриплета. Вы должны знать, что скриплет может воздействовать на объекты, которые видимы для него.

    JSP выражения можно найти вперемешку с HTML в среднем разделе Hello.jsp. Выражения должны быть законченными Java инструкциями, которые вычисляются, переводятся в строку и посылаются в вывод. Если результат инструкции не может быть переведен в строку (String), будет выброшено исключение ClassCastException.

    Извлечение полей и значений

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

    Введение в JSP.

    Начнем с того, где мы будем хранить наш код и как обмениваться им с друзьями. Думаю, не все начинающие знают про репозитории, и эта часть именно для них.

    После всего этого у Вас будет ссылка на Ваше пространство. Чтобы понять, что это такое — нужно взять один из ваших проектов (или создайте какой нибудь пустой проект в NetBeans). Нажимаете на нем правой кнопочкой и у Вас в меню будет доступно «Управление версиями» -> «импортировать в репозиторий Subversion». После этого будет диалоговое окно, в котом будет путь к репозиторию — это ссылка которую Вы получили на сайте во вкладке «Исходный код».

    Далее, полностью удалите проект, который вы закоммитили. Дальше зайдите в папку, где у вас проекты хранятся, и проверьте что реально все удалено. Потом возвращаетесь в NetBeans и ищете в панели меню вкладку Группа(на панели где Файл, Вид, Правка, Переход, Источник. ) в нем есть наш Subversion. И в подменю на нем есть «Получить». Дальше в диалоговых окнах надо будет указать ссылку на репозиторий (это ссылка которую вы получили на сайте во вкладке «Исходный код».) И когда он предложит выкачивать папки, то по дереву репозитория нужно будет найти ваш проект и выбрать его, и по окончанию вы выкачаете свой проект. Вот так происходит обмен кодом.
    Ваш проект будет постоянно синхронизироваться с репозиторием и помечать файлы, которые были изменены, или новые(то что отличается от версии на репозитории). Чтобы обновить, нужно вызвать контекстное меню, и в закладке «Управление Версиями» будет большой список того, что можно делать с проектом. «Обновлять» — это обновить свои файлы; «Фиксировать» — ложить код который Вы написали или изменили в репозиторий; «Сбрасывать» — возвращаться к версии на репозитории, и «Сравнивать» — отображение изменений строк которые отличаются от удаленных. Это способ командного обмена кодом, который используется всегда и нужно к нему привыкать.

    Вы уже скачали NetBeans, поигрались с SVN — теперь перейдем к делу. Создаете проект. Нажимаете «Создать проект», там выбираете Maven-> Веб-приложение. Называете как хотите, это все Ваша фантазия. Итак, у нас есть веб-приложение, сборка нашего проекта идет мавеном, у нас есть цель и теперь наступило время подумать над тем, как ее осуществить. То есть Вы, как разработчик, должны подумать над тем, как будет выглядеть Ваше приложение, какую иметь архитектуру, дерево пакетов и так далее. Общее количество строк кода здесь около 4000 и лучше позаботиться о красивой архитектуре заранее, иначе потом Вы просто не будете понимать что где и как у Вас работает, каким чудом Вы, к примеру, выводите последнюю купленную вещь, как считаете общую сумму покупок. И если Вас потом попросят что-то доделать или добавить — Вы осознаете что проще написать все с нуля.

    Ну и конечно нам нужно прикинуть наш план действий.

    Итак: План действий

    2) Создаем HibernateUtil (вообще суффикс или приставка Util подразумевает, что код в этом классе есть универсальный и используется множеством классов).
    Итак, в HibernateUtil мы размещаем SessionFactory. Он тяжеловесный. Этот код, по идее, должен быть независим от всего приложения, так как он устанавливает соединение с базой данных при старте и должен нам давать только Сессии с базой данных. Еще мы в этом классе регистрируем наши классы-сущности. Подробнее про этот класс расскажу позже. Засунем его тоже в отдельный пакет, к примеру, edu.shop.model.hbutil.HibernateUtil.java

    3) Пишем DAO.
    Что в нем писать? Пишем то, что мы хотим получить от базы данных, но нам не нужно думать как получились эти данные, важен результат. К примеру, мы определяем интерфейс ProductDAO и пишем в нем методы
    List> getAllProducts(); потом пишем его реализацию ProductDAOImpl.

    В чем идея? Если бы это приложение писал я и Вы, Вы бы сказали: «Миха, мне нужны от БД следующие данные: все товары что у меня есть в БД». Я отвечаю: «не вопрос». И далее следующее развитие событий: вы в своем коде, везде где нужно делать запросы к базе пишете следующее%

    *здесь обращение к методу*.getAllProducts(); — и видите, что компилятор не ругается, а реализацию этого интерфейса я мог еще не успеть написать. И какой итог? У Вас все скомпилилось, а рабочего кода даже нет. Здесь мы применим Enums и паттерн Factory, и еще кое-что, но всему свое время. Именно в DAO нужно уделить особое внимание обработке исключений, хотя бы генерировать страницы с ошибками. Чтобы Вы быстро находили кусок неработающего кода. Иначе, Вы просто замучаетесь с отладкой.

    3)Здесь начнется наша работа с Spring MVC. Это долгая история и этому будет посвящена отдельная статья. Сразу скажу — это самое сложное в этом приложении. Но я Вам покажу и более простой вариант, как выводить все, не особо заботясь про паттерн MVC.
    Затронем использование скриплетов.

    4) Здесь у нас будут вспомогательные классы, добавляющие всякие вкусности в наш проект: подсчет общей суммы покупок; последняя купленная вещь; вспомогательные переменные, которые пригодятся нам для работы метода, который, к примеру, будет выводить нам с БД вещи не дороже 5000 грн, или не дешевле 500; вывод всех ноутбуков марки Асус. Этот пункт тесно взаимосвязан с предыдущим.

    Пока остановимся на этом. С остальным разберемся чуть позже. Итак, у нас есть намеченный план, приступим к его реализации.

    Entity

    Примечание. Корзина, в которой будут храниться наши купленные товары, будет как таблица в БД, это я сделал т.к на ней покажу некоторые основы работы с БД. Для реального случая целесообразнее будет использовать коллекции для хранения наших товаров.

    1) Product
    2) Notebook
    3) Camera
    4) Book
    5) Cable
    6) Customer
    7) Cart

    Поговорим немного о том, что такое класс-сущность.
    Entity (Сущность) — POJO-класс, связанный с БД с помощью аннотации (@Entity) или через XML. К такому классу предъявляются следующие требования:

    Должен иметь пустой конструктор (public или protected);
    — Не может быть вложенным, интерфейсом или enum;
    — Не может быть final и не может содержать final-полей/свойств;
    — Должен содержать хотя бы одно @Id-поле.

    При этом entity может:

    Entities могут быть связаны друг с другом: один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим.

    Использовать мы будем аннотации. И тут сразу у нас появляется возможность описать двумя способами. Либо мы будем писать аннотации непосредственно над полями, либо над геттерами. Скажу одно: правильно писать над геттерами, а причину Вы спросите в гугле. Не могу я все темы абсолютно здесь описать.

    Есть еще одно что хочу сказать. Для этого придется показать 2 примера описания класса сущности. Итак, первый пример:
    Коментарии к нему я написал в самом коде:

    Import java.io.Serializable; import javax.persistence.*; import javax.val ) private Integer price; public CartEntity() < >public CartEntity(String nameItem, int price) < this.nameItem = nameItem; this.price = price; >public CartEntity(Integer >

    Второй способ: пишем над геттерами. Пояснения смотрим в коде.

    Теперь приведем пример нашего HibernateUtil

    Его смысл:
    — Весь доступ к базе данных в системе производится через DAO для инкапсуляции.
    — Каждый экземпляр DAO отвечает за один первичный доменный объект или сущность. Если доменный объект имеет независимый цикл жизни, он должен иметь свой собственный DAO.
    — DAO отвечает за операции создания, чтения (по первичному ключу), обновления и удаления (то есть, CRUD (create, read, update, delete)) доменного объекта.
    — DAO может разрешать запросы, основанные на критерии, отличном от первичного ключа. Я ссылаюсь на такие методы как finder или finders. Метод finder обычно возвращает коллекцию доменных объектов, за которые отвечает DAO.
    — DAO не занимается обработкой транзакций, сессий или соединений. Это делается вне DAO для обеспечения гибкости.
    Подробнее всегда расскажет гугл.

    Мы пока напишем DAO для наших продуктов.
    Итак, подумаем что нам вообще нужно. Таблица Product будет иметь 4 поля Id,nameProduct,available+amount+actionForServlet. Она нам будет нужна, чтобы создать на нашем сайте категории. Над последним полем пока не заморачиваемся. Единственное что нам нужно — это получение списка продуктов.

    GetProducts(); //и метод с которым мы будем работать >

    Реализация нашего интерфейса. Пояснения смотрим в коде
    /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package edu.shop.model.dao; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; /** * * @author Mikhail Shumenko */ public class ProductDAOImpl implements ProductDAO < @Override public List

    Итак, теперь у нас есть возможность получать данные из БД. Вы можете, используя скриплеты, создать незамысловатый цикл for-each и вывести свою продукцию на вашу страницу index.jsp

    Категории

    Категория

    //INSTANCE_PRODUCT что это такое? //В ProductDAO описана такая переменная, отвечает за создание ProductDAOImpl //Ну у нас все будет по-другому, можете особо не запоминать это. //ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl();

    «> Наличие

    Но это на первое время, а вообще так делать плохо. Это нарушает наш паттерн MVC. Как сделать правильно я объясню в следующем уроке, если мне дадут инвайт. Во втором уроке мы займемся Spring, в третьем коснемся паттерна Factory, и углубимся в хибернейт. Для особо нетерпеливых, покажу как нужно удалять из БД, сохранять в БД и удалять полностью все из БД. Ну, а как сделать, чтобы все это взаимодействовало в целом с нашим приложением и подробное рассмотрение оставим на потом.

    Сохранить в БД

    О том, как заполнять наши БД поговорим позже. Можете заполнить их вручную. Либо дождаться следующего урока.

    Как мы уже видели в предыдущей статье, сервлеты позволяют нам получать запросы от клиента, совершать некоторую работу и выводить ее результаты на экран. До того момента, как надо осуществлять вывод на экран сервлет прекрасно работает. В него можно вставить достаточно сложную логику, сделать вызовы к базе данных и многое-многое другое, что необходимо для приложения. Но вот осуществлять вывод на экран внутри самого сервлета — очень неудобно. В нашем примере мы ограничились крайне простым решением. А что придется делать в случае вывода сложных дизайнерских идей? Вряд ли Web-дизайнер сможет понять, как надо осуществлять вывод внутри нашего сервлета. И когда он захочет осуществить свои дизайнерские идеи, то ему придется приходить к программисту и просить поменять код сервлета для того, чтобы изменить дизайн. Это надо будет перекомпилировать, надо будет придумывать умные алгоритмы для вывода не только картинок, но и того же JavaScript. Просто кошмар.
    Каждому здравомыслящему разработчику ясно, что надо использовать иное решение. Самое очевидное – придумать механизм, который разделил бы задачу на две составляющие: одна часть обрабатывает запрос, меняет данные, собирает данные, укладывает это в некий пакет и передает второй части, которая делает только одно – показывает эти данные.
    Так мы подошли к уже известному нам петтерну – Model-View-Controller (MVC). Для случая Web-приложений контроллером у нас становится сервлет, пакет данных, который мы сформировали – моделью. А вот на роль представления (View) прекрасно подходит JSP – Java Server Pages.
    В этой статье мы сделаем общий обзор этой технологии. А «Отдел кадров» продолжим в следующей статье, где сможем сразу использовать знакомые технологии – сервлеты и JSP.
    Основная идея JSP очень проста – сама страница пердставляет из себя шаблон с уже заготовленными HTML-тэгами, между которыми надо вставить нужные данные. Что-то вроде такого (это только схема)

    Hello World Sample

    [И тут какие-то данные]

    Чтобы вам не было скучно и для наглядности давайте изменим наш самый первый сервлет HelloWorldServlet из предыдущей статьи. Мы добавим ему возможность работать с параметром, который передадим с помощью URL. Его мы увидим чуть позже. А пока давайте посмотрим на несколько измененный сервлет HelloWorldServlet. Его задача сейчас очень проста – вывести приветствие «Hello, world !» в случае если не будет передано параметра name. Если же он передан, то приветствие несколько изменится. Например, при передаче параметра name=Antonсервлет должен вывести надпись «Hello, world. I’m Anton».
    Ничего сложного в задаче нет и ее можно решить без JSP, но для демонстрации нам подойдет.

    package students.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorldServlet extends HttpServlet < public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException < getServletContext().getRequestDispatcher("/hello.jsp").forward(req, resp); >>

    package students . web ;

    import javax . servlet . ServletException ;

    import javax . servlet . http . HttpServlet ;

    import javax . servlet . http . HttpServletRequest ;

    import javax . servlet . http . HttpServletResponse ;

    public class HelloWorldServlet extends HttpServlet <

    public void doGet (HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException <

    Илон Маск рекомендует:  Постраничный вывод на PHP
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL