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

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 выражение (<%=), результат вычислений преобразуется в строку, а затем поместится в сгенерированную Web страницу:

//:! c15:jsp:ShowSeconds.jsp < html >< body > < H1 > The time in seconds is : <%= System . currentTimeMillis ()/ 1000 %> ///:~

В 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 контейнеру и обозначаются символом "@":

<% @ directive { attr = "value" }* %>

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

<% @ page language = "java" %>

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

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

<% @ page session = "true" import =" java . util .*" %>

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

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

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

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

<%! declaration %> <% scriptlet %> <%= expression %>

Пробелы после "<%!", "<%", "<%=" и перед "%>" не обязательны.

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

< jsp : declaration > declaration < jsp : scriptlet > scriptlet < jsp : expression > expression

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

<%-- jsp comment --%>

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

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

//:! c15:jsp:Hello.jsp <%-- Этот JSP комментарий не появится в сгенерированном html -- %> <%-- Это JSP директива: -- %> <%@ page import="java.util.*" %> <%-- Эта декларации: -- %> <% ! long loadTime = System.currentTimeMillis (); Date loadDate = new Date (); int hitCount = 0 ; %> <%-- Следующие несколько строк являются результатом JSP выражений, вставленных в сгенерированный html; знак "=" указывает на JSP выражение -- %>

Эта страница была загружена <%= loadDate %>

Hello, world! It"s <%= new Date () %>

Here"s an object: <%= new Object () %>

This page has been up <%= (System.currentTimeMillis ()- loadTime )/ 1000 %> seconds

Page has been accessed <%= ++ hitCount %> times since <%= loadDate %>

<%-- "Скриплет", которые пишет на консоли сервера и на странице клиента. Обратите, что необходимо ставить ";": -- %> <% System.out.println ("Goodbye" ); out.println ("Cheerio" ); %> ///:~

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

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

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

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

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

//:! c15:jsp:DisplayFormData.jsp <%-- Извлечение данных из HTML формы. -- %> <%-- Эта JSP также генерирует форму. -- %> <%@ page import="java.util.*" %>

DisplayFormData

<% Enumeration flds = request.getParameterNames (); if (! flds.hasMoreElements ()) { // Нет полей %>
<% for (int i = 0 ; i < 10 ; i ++) { %> Field <%= i %> :
<% } %>
<% } else { while (flds.hasMoreElements ()) { String field = (String ) flds.nextElement (); String value = request.getParameter (field ); %>
  • <%= field %> = <%= value %>
  • <% } } %>

    ///:~

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

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

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

    //:! c15:jsp:PageContext.jsp <%-- Просмотр атрибутов pageContext-- %> <%-- Обратите внимание, что вы можете включить любое количество кода внутри тэгов скриплета -- %> <%@ page import="java.util.*" %> Servlet Name: <%= config.getServletName () %>
    Servlet container supports servlet version: <% out.print (application.getMajorVersion () + "." + application.getMinorVersion ()); %>
    <% session.setAttribute ("My dog" , "Ralph" ); for (int scope = 1 ; scope <= 4 ; scope ++) { %>

    Scope: <%= scope %>

    <% Enumeration e = pageContext.getAttributeNamesInScope (scope ); while (e.hasMoreElements ()) { out.println ("\t
  • " + e.nextElement () + "
  • " ); } } %> ///:~

    Этот пример также показывает использование встроенного 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. Следующие примеры исследуют сессионные объекты и позволяют вам манипулировать промежутком времени, прежде, чем сессия станет недействительной.

    //:! c15:jsp:SessionObject.jsp <%-- Получение и установка значений объекта сессии -- %>

    Session id: <%= session.getId () %>

  • This session was created at <%= session.getCreationTime () %>
  • Old MaxInactiveInterval = <%= () %>
  • <% session.setMaxInactiveInterval (5 ); %>
  • New MaxInactiveInterval= <%= session.getMaxInactiveInterval () %>
  • If the session object "My dog" is still around, this value will be non-null:

  • Session value for "My dog" = <%= session.getAttribute ("My dog" ) %>
  • <%-- Теперь добавим объект сессии "My dog" -- %> <% session.setAttribute ("My dog" , new String ("Ralph" )); %>

    My dog"s name is <%= session.getAttribute ("My dog" ) %>

    <%-- See if "My dog" wanders to another form -- %>
    < /FORM>
    ///:~

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

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

    Session value for "My dog" = Ralph

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

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

    //:! c15:jsp:SessionObject2.jsp <%-- Объект сессии переноситься -- %>

    Session id: <%= session.getId () %>

    Session value for "My dog" <%= session.getValue ("My dog" ) %>

    <% session.invalidate (); %> ///:~

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

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

    //:! c15:jsp:SessionObject3.jsp <%-- Переход объекта сессии по страницам -- %>

    Session id: <%= session.getId () %>

    Session value for "My dog" <%= session.getValue ("My dog" ) %>

    ///:~

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

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

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

    //:! c15:jsp:Cookies.jsp <%-- Эта программа ведет себя по разному в разных броузерах! -- %>

    Session id: <%= session.getId () %>

    <% Cookie cookies = request.getCookies (); for (int i = 0 ; i < cookies.length ; i ++) { %> Cookie name: <%= cookies [ i ]. getName () %>
    value: <%= cookies [ i ]. getValue () %>
    Old max age in seconds: <%= cookies [ i ]. getMaxAge () %>
    <% cookies [ i ]. setMaxAge (5 ); %> New max age in seconds: <%= cookies [ i ]. getMaxAge () %>
    <% } %> <% ! int count = 0 ; int dcount = 0 ; %> <% response.addCookie (new Cookie ("Bob" + count ++, "Dog" + dcount ++)); %> ///:~

    Так как каждый браузер хранит 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

    2. Измените значение максимального возраста в Cookies.jsp и пронаблюдайте поведение в различных браузерах. Также обратите внимание на различие между повторным посещением страницы и выгрузкой/загрузкой браузера. Если у вас нет существующего JSP контейнера, вам необходимо загрузить, установить и запустить Tomcat с сайта jakarta.apache.org , чтобы иметь возможность запускать JSP.
    3. Создайте JSP с одним полем, которое позволяет пользователю вводить время действия сессии, и со вторым полем, которое содержит данные, хранящиеся в сессии. Кнопка отсылки обновляет страницу и получает текущее время действия сессии и данные сессии, а потом помещает их в качестве значения по умолчанию в вышеупомянутые поля. Если у вас нет существующего JSP контейнера, вам необходимо загрузить, установить и запустить Tomcat с сайта jakarta.apache.org , чтобы иметь возможность запускать JSP.

    Cервлеты позволяют получать запросы от клиента, совершать некоторую работу и выводить результаты на экран. Сервлет прекрасно работает до того момента, пока речь идет об обработке информации, т.е. до вывода информации на экран. В сервлет можно вставить достаточно сложную логику, сделать вызовы к базе данных и многое-многое другое, что необходимо для приложения. Но вот осуществлять вывод на экран внутри самого сервлета - очень неудобно. А как быть при разработке сложных дизайнерских идей и последующее внесение изменений в пользовательский интерфейс? Технология проектирования 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

    Технология Java Server Pages содержит четыре ключевых компонента:
    1. Директивы (directive) представляют собой сообщения для контейнера JSP, дающим возможность определить параметры страницы, подключения других ресурсов, использовать собственные нестандартные библиотеки тегов.
    2. Действия (actions) инкапсулируют функциональные возможности в предопределенных тегах, которые можно встраивать в JSP-страницу. Действия часто выполняются на основе информации, посылаемой на сервер в составе запроса от определенного клиента. Действия также могут создавать объекты Java для использования их в скриптлетах JSP.
    3. Скриптлеты (scriptlets) позволяют вставлять код Java в страницы JSP, который взаимодействует с объектами страницы при обработке запроса.
    4. Библиотеки тегов (tag library) являются составной частью механизма расширения тегов, допускающего разработку и использование собственных тегов.
    Наличие данных с неизменяемой структурой определяют выбор программиста в принятии решения, какую технологию следует использовать: сервлеты или страницы 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 тега <%@ page> . Наличие буфера позволяет заносить заголовки ответа в выходной поток совместно с выводимым текстом. В буфере заголовки будут размещены перед текстом. Таким образом, достаточно написать страницу JSP, сохранить ее в файле с расширением jsp и установить файл в контейнер, так же, как и страницу HTML, не заботясь о компиляции. При установке можно задать начальные параметры страницы JSP так же, как и начальные параметры сервлета.

    Последнее обновление: 02.09.2018

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

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

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

    В данном случае для работы с JSP мы будем использовать Apache Tomcat, который одновременно является и веб-сервером и контейнером сервлетов и JSP.

    Создадим простейшую страницу JSP. Для этого где-нибудь на жестком диске определим файл index.jsp . Все станицы JSP имеют расширение jsp . Откроем этот файл в любом текстовом редакторе и определим в нем следующий код:

    <% String header = "Apache Tomcat"; %> First JSP App

    <%= header %>

    Today <%= new java.util.Date() %>

    С помощью тегов <% ... %> мы можем определить код Java на странице JSP. В данном случае мы просто определяем переменную типа String, которая называется header.

    Затем идет стандартный код страницы html. Чтобы внедрить код java внутрь html-страницы применяются теги <%= %> - после знака равно указывается выражение Java, результат которого будет выводиться вместо этих тегов. В данном случае, используются две таких вставки. Первая вставка - значение переменной header, которая была определена выше. Вторая вставка - выражение new java.util.Date() , которое возвращает текущую дату.

    Для тех, кто знаком с веб-разработкой на PHP, это может напоминать оформление файлов php, которые также содержать код html и код php.

    Теперь поместим данный файл на сервер - в данном случае в контейнер Tomcat. Перейдем в Apache Tomcat к папке webapps\ROOT . Удалим из нее все содержимое и поместим нашу страницу index.jsp , которая была создана выше.

    Запустим Apache Tomcat (если он не запущен), и обратимся к приложению по адресу http://localhost:xxxx/index.jsp , где xxxx - номер порта, по которому запущен Tomcat:

    В итоге Tomcat получит запрос к странице index.jsp, обработает код на java, сгенерирует html-страницу и отправит ее пользователю.

    По умолчанию Apache Tomcat настроен таким образом, что все запросы к корню приложения по умолчанию обрабатываются страницей index.jsp, поэтому мы также можем обращаться к ней по адресу

    Технология Java Server Pages (tm) (JSP) позволяет разработчикам и дизайнерам web-приложений быстро разрабатывать и легко сопровождать web-страницы с динамическим наполнением информацией. Но описание практически каждой технологии подобного назначения (ASP, PHP, Net.Data) сопровождают подобные слова -- быстро и легко...

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

    Сначала простое перечисление:

    • действительно высокая межплатформенная переносимость; использование универсального языка высокого уровня Java в качестве скриптового;
    • JSP -- это не какое-то отдельно стоящее средство для решения достаточно узкого круга задач, пусть и достаточно мощное, а ещё одно в ряде целой плеяды технологий, объединяемых Java;
    • реальная возможность разделить задачи написания бизнес-логики web-приложения и пользовательского интерфейса, что позволяет разрабатывать и сопровождать различные части проекта независимо;
    Технология JSP является прямым расширением ещё одной Java-технологии -- Servlets (tm) а также тесно связана с технологией Java Beans (tm) и использует XML-подобные теги (tags) и скриптлеты (scriptlets), написанные на языке программирования Java для введения логики создания динамического наполнения web-страницы, при этом HTML или XML-теги передаются клиентской стороне напрямую.

    Количество тегов достаточно невелико, что упрощает начальное освоение данной технологии; впрочем, для простых вещей та же Net.Data или PHP тоже весьма просты. Как водится, рассмотрим примитивный случай класса Hello World!
    <%@ page contentType="text/html; charset=ibm866" %> <%@ page import ="java.net.*" %> <%@ page import ="java.util.Date" %> Who Am I? <% InetAddress localHost = InetAddress.getLocalHost(); Date localTime = new Date(); %>

    Who Am I?

    I am called <%= localHost.getHostName() %> (<%= localHost.getHostAddress() %>).
    This page last executed at <%= localTime.toString() %>.

    Даже у человека, не знающего Java, понимание вышеприведенного кода, скорее всего, не вызовет проблем. Остановимся на некоторых моментах: код, находящийся внутри тегов <% %> , собственно и есть код скриптлета; всё находящееся между <%-- --%> -- комментарий; тег <%= позволяет вывести значение переменной в нужном месте страницы; <%@ page %> позволяет импортировать классы и также настраивать некоторые особенности в поведении страницы.

    Если мощь таких конкурирующих (наверное, это всё-таки так;-) инструментов, как PHP и Net.Data, обусловлены в первую очередь огромным набором предопределённых функций, то за JSP стоит весь конгломерат классов и технологий Java.

    Но на таком простом примере вовсе не очевидно, почему нужно выбрать JSP и всё с ними связанное, в первую очередь servlets и beans. Тем не менее попытаемся рассмотреть некоторые приятные стороны JSP.

    Session Management

    Значения, которые сохраняются и извлекаются из объекта сессии, не могут быть примитивными типами данных (int, double) и должны быть представлены в виде своих классов-аналогов (Integer, Double).
    HttpSession session=request.getSession();//get session object or create one session.getId() //get the session ID number Integer item = (Integer) session.getValue("item") // retrieve Integer object session.putValue("ItemValue", itemName);//ItemValue must not be primitive

    Application Management

    Иногда необходимо обеспечить сервером некоторых значений переменных на уровне сайта, каждый клиент использует и манипулирует копиями этих данных. JSP использует объект ServletContext, который обеспечивает механизм, схожий с сессией (i.e. no primitive types).
    getServletContext().setAttribute("Item", ItemValue);//to set an application variable Integer i=(Integer)getServletContext().getAttribute("ItemName");//get item color=blue>

    JSP-Specific Language

    Директивы JSP "говорят" серверу делать что-либо, когда они преобразуются из JSP в сервлет; директивы предваряются символом @. Некоторые важные директивы JSP перечислены ниже, для более полного знакомства естественно придется почитать что-то ещё.
    include - включение статического или динамического файла (Server Side Include) <%@ include file="hello.jsp" %> import - итоговый сервлет будт импортировать данный пакет <%@ import = "java.util.*" %> extends - сервлет будет расширять (наследовать) указанный класс (это superclass) <%@ extends = "java.util.Dictionary" %> implements - сервлет будет имплементировать интерфейс <%@ implements = "java.util.Enumeration" %> content_type - устанавливает тип ответа, генерируемого сервлетом <%@ content_type = "text/plain" %> или <%@ content_type = "text/html" %>

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

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

    Есть два варианта include:

    • Статическое включение , при этом обрабатываются JSP-элементы во включаемом файле, если они есть и попадают в результирующий сгенерированый Java-код, фактически серлет:
      <%@ include file="includeheader.jsp"%>
      или так
      <%@ include file="includeheader.html"%>
      то есть включаемый файл вовсе не обязан быть JSP страницей.
    • Динамическое включение , при этом контент включаемого файла обрабатывается независимо, фактически ему передается управление на момент выполнения:
    Что интересно, динамически включенный контент может кэшироваться независимо, что в некоторых случаях даёт существенный выигрыш на сложных многокомпонентных страницах. Но возможность include тем не менее, наверное, самое примитивное из многогранных возможностей JSP.

    Практически каждый, начав делать web-приложение, сталкивается с необходимостью предоставить пользователю удобное средство для ввода информации, и тут, как правило, возникают бо льшие проблемы, чем просто с предоставлением информации в виде сгенерёных HTML-страниц. Необходимо обеспечить достаточную интеллектуальность ввода, кроме того, при ошибках ввода не терять ранее введённое и передавать требуемую общую информацию от страницы к странице. В Net.Data, например, я не нашёл способа делать это иначе, чем использовать hidden-поля в формах ввода, хранение же информации с временем жизни "session" вырастает в сложную задачу; как можно выкрутиться с решением этой задачи в PHP, я не в курсе. Что же касается JSP/servlets -- есть стандартное средство JavaBeans (в данном контексте не будем останавливаться на таком более мощном развитии данной концепции, как EJB) -- это полноценные классы Java с некоторыми дополнительными правилами программирования.

    Это очень мощное средство, но оно требует некоторой ломки стереотипов. JavaBeans -- это компоненты Java, которые могут выполнять хорошо определённые задачи и включать в себя объекты данных. JavaBeans следуют структурной объектной модели: Bean имеет public constructor, который не имеет аргументов, и его свойства устанавливаются с помощью управляющего сервлета с использованием интроспекции (introspection/reflection).

    Включение некоторого бина в "страницу" JSP делается например так:

    ... Дополнение <%=formHandler.getErrorMsg("description")%> Владелец <%= formHandler.getOwnerName()%> | <%= formHandler.getOwnerName()%> <%=formHandler.getErrorMsg("owner")%> ===> или вот ещё один
    I like <%= Cindy.getFlavor() %> coffee. //The Coffee Bean: Public class Coffee { private String m_flavor; public Coffee() { m_flavor = "Regular"; } public void setFlavor(String flavor) { m_flavor = flavor; } public String getFlavor() { return m_flavor; } }

    Некоторые пояснения к этой выжимке: scope="request" означает, что время жизни бина -- request, property="*" означает, что данный бин принимает с помощью своих методов все параметры, переданные в запросе на данную страницу. Эти методаы имеют простое правило именования: если параметр формы -- lastName, то метод, принимающий данные, будет иметь имя setLastName, а отдающий данные -- getLastName.

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

    Генеральная линия, которая прослеживается во множестве публикаций последнего времени -- разделение работы дизайнера и работы программиста, обеспечивающего написание собственно работы с базой данных и бизнес-логику web-приложения. Большая часть этого может быть вынесена именно на уровень бинов. К сожалению, трудоемкость написания, по крайней мере на начальном этапе, у связки JSP-servlets-beans выглядит большей, чем у Net.Data и PHP (впрочем, с последним я знаком на уровне чуть большем "Hello World!"). Но даже использование бинов не освобождает совсем от минимального использования Java на странице. Чтобы дойти до логического конца и оставить дизайнеру только правильную расстановку тегов на странице, в JSP ввели возможность написания библиотек тегов (custom JSP tag libraries).

    Использование библиотек тегов позволяет, во первых, ещё повысить повторное использование кода, во вторых, снизить сложность написания прриложения, и, в третьих, ещё больше помочь в разделении труда. К сожалению, последнее в нашей действительности ещё не приобрело должного веса при выборе средства разработки. В заключение приведу небольшой пример использования пользовательских тегов, например, запрос к базе с выводом результата в виде таблицы может выглядеть вот так:
    <%@ taglib uri="xsql.tld" prefix="xsql" %> ...

    что-тонечтоописание
    "$1$""$2$""$3$"
    но это вовсе не значит, что он должен так выглядеть;-)

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

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

    Hello World Sample <TITLE> </HEAD> <BODY> <H1> [И тут какие-то данные] </H1> </BODY> </HTML></p> <p>Чтобы вам не было скучно и для наглядности давайте изменим наш самый первый сервлет HelloWorldServlet из предыдущей статьи. Мы добавим ему возможность работать с параметром, который передадим с помощью URL. Его мы увидим чуть позже. А пока давайте посмотрим на несколько измененный сервлет HelloWorldServlet. Его задача сейчас очень проста – вывести приветствие «Hello, world !» в случае если не будет передано параметра name. Если же он передан, то приветствие несколько изменится. Например, при передаче параметра name=Antonсервлет должен вывести надпись «Hello, world. I’m Anton».<br> Ничего сложного в задаче нет и ее можно решить без JSP, но для демонстрации нам подойдет.</p> <p>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); } }</p> <table class="crayon-table"><tr class="crayon-row"><td class="crayon-nums " data-settings="show"> </td> <td class="crayon-code"><p>package students . web ; </p><p>import javax . servlet . ServletException ; </p><p>import javax . servlet . http . HttpServlet ; </p><p>import javax . servlet . http . HttpServletRequest ; </p><p>import javax . servlet . http . HttpServletResponse ; </p><p>public class HelloWorldServlet extends HttpServlet { </p><p>public void doGet (HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException { </p><p>getServletContext () . getRequestDispatcher ("/hello.jsp" ) . forward (req , resp ) ; </p> </td> </tr></table><p>Самая интересная строка (она же пока и единственная) позволяет нам получить ресурс (в нашем случае это hello.jsp) и передать этому ресурсу наши данные. В данном случае мы ничего не меняли и не добавляли. Теперь давайте посмотрим на файл hello.jsp, который должен представить пользователю некую страницу. В данном случае она не очень сложная, но все-таки мы остановимся на ней подробнее.</p> <p><html> <head> <title> Hello World Sample

    <% String name = request.getParameter("name"); if (name == null || name.length() == 0) { %> Hello, world ! <% } else { %> Hello, world ! I"m <%= name%> <% } %>

    < html >

    < head >

    < title >

    Hello World Sample

    < / title >

    < / head >

    < body >

    < h1 >

    String name = request . getParameter ("name" ) ;

    if (name == null || name . length () == 0 ) {

    Hello , world !

    <% } else {

    Hello , world ! I "m <%= name %>

    < / h1 >

    < / body >

    < / html >

    Как видите наш HTML-файл представляет из себя смесь тэгов для HTML и кода на Java. По сути JSP при первом обращении преобразуется в сервлет и работает уже как сервлет. Это очень важно понять. JSP НЕ ЯВЛЯЕТСЯ страницей наподобие HTML-страницы — начинающему програмисту важно четко осознавать, что это еще один сервлет — просто его вывод не надо программировать. Его можно просто нарисовать. И в нужные места подставить данные. Но т.к. JSP-страница хоть как-то напоминает HTML, то дизайнеру явно будет проще. И я еще раз НАСТОЙЧИВО говорю начинающим — JSP является СЕРВЛЕТОМ. Ее подготовка со всеми данными происходит на сервере. Именно там подставляются все данные. А пользователю в броузер приходит уже готовая HTML-страница, на которой никаких признаков JAVA нет. Разве что апплет какой-нибудь — но это уже совсем другая технология. Просто JSP удобно использовать — вы делаете логику получения данных в одном сервлете (который не выглядит как JSP) и потом передаете данные другому сервлету (на этот раз в виде JSP), задача которого с помощью этих данных нарисовать HTML-страничку. Только рисовать надо не так много. К тому же вам не надо перекомпилировать классы JSP. Можно просто заменить JSP на более современную и она автоматичски будет скомпилирована заново. Что в общем-то достаточно удобно — просто скопировали нужную страничку на место старой. Как можно видеть код Java заключается в угловые скобки со знаком процента «<%» и здесь вам можно написать любой код, который будет нужен.
    Как видите наш код проверяет наличие параметра name в запросе (request.getParameter(«name»)) и, если он существует, то выводится одна надпись. В противном случае мы увидим «укороченный» вариант надписи.
    Еще немного информации — JSP имеет в своем составе несколько предопределенных объектов. Т.е. их надо воспринимать, как уже готовые объекты, которые могут быть использованы. Это request, response, out, session, application, config, pageContext и page. Я дам коротенькую справку на них, возможно, что это пока будет не очень интересно, да и не понятно. Но на всякий случай.

    request
    Это объект HttpServletRequest, связанный с запросом, который позволяет вам обращаться к параметрам запроса (через метод getParameter), типу запроса (GET, POST, HEAD, и т.д..), и входящим HTTP заголовкам (cookies, Referer, и т.д..). Если быть более точным, request является подклассом ServletRequest и может отличаться от HttpServletRequest если используется протокол отличный от HTTP, что на практике практически никогда не встречается. Поэтому про него можно думать, что это HttpServletRequest.

    response
    Это объект типа HttpServletResponse, связанный с ответом на запрос клиента. Обратите внимание что, поскольку поток вывода (см. out далее) буферизован, можно изменять коды состояния HTTP и заголовки ответов, даже если это недопустимо в обычном сервлете, но лишь в том случае если какие-то данные вывода уже были отправлены клиенту.

    out
    Это объект типа PrintWriter, используемый для отправки вывода клиенту. Однако, чтобы сделать объект response (см. предыдущий раздел) полезным, следует использовать буферизированный вариант PrintWriter — JspWriter. Помните что вы можете изменять размер буфера и даже отключить буферизацию, изменяя значение атрибута buffer директивы page. Также обратите внимание что out используется практически исключительно скриплетами, поскольку выражения JSP автоматически помещаются в поток вывода, что избавляет от необходимости явного обращения к out.

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

    application
    Это объект типа ServletContext полученный через использование метода getServletConfig().getContext().

    config
    Это объект типа ServletConfig для текущей страницы.

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

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

    Давайте все-таки посмотрим на наше творение в действии. Скомпилировать наш сервлет можно командой

    javac –cp .;servlet-api.jar students\web\*.java

    После этого поместим наш класс HelloWorldServlet в каталог \webapps\studentsApp\WEB-INF\students\web\. А файл hello.jsp в корневой каталог нашего приложения — \webapps\studentsApp.
    Теперь наше дерево каталогов несколько проще (мы не используем некоторые классы)

    WEB-INF classes students web -HelloWorldServlet.class -web.xml -hello.jsp

    < strong > WEB - INF

    classes

    students

    HelloWorldServlet . class

    Web . xml

    Hello . jsp < / strong >

    Уже известный файл web.xml будет выглядеть точно так же, как и в предыдущей части

    hello hello /hello

    < ! DOCTYPE web - app PUBLIC "-//Sun Microsystems, Inc.//DTD

    Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >

    < web - app >

    < servlet >

    < servlet - name > hello < / servlet - name >

    < servlet - class > students . web . HelloWorldServlet < / servlet - class >

    < / servlet >

    < servlet - mapping >

    < servlet - name > hello < / servlet - name >

    < url - pattern > / hello < / url - pattern >

    < / servlet - mapping >

    < / web - app >

    Запускаем Tomcat и потом попробуйте вызвать наше приложение по URL
    http://localhost:8080/studentsApp/hello

    Если же хотите увидеть мое имя используйте такой URL
    http://localhost:8080/studentsApp/hello?name=Anton
    Свое имя можно подставить потом 🙂

    Custom Tag

    Теперь мы можем окунуться немного глубже в JSP. Как вы уже наверняка заметили JSP представляет собой эдакую смесь Java-кода и тэгов HTML. При увеличении сложности логики представления (а JSP используется именно в качестве представления – но даже представление может иметь достаточно изощренную логику – цвета, шрифты и прочая) страница из более-менее понятного HTML превращается в «макароны по-флотски». И дизайнер уже не будет способен что-либо понять. Абсолютно избавиться от логики в JSP скорее всего не получится, но как-то «причесать» код и использовать более удобные средства – такое решение существует. И оно называется CustomTags. По сути это упрощение конструкций JSP, которого хотелось достичь.

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

    1. Написать TLD-файл (Tag Library Definition) – файл описателя библиотеки тэгов.
    2. Написать класс для реализации самого тэга
    3. Исправить HTML-файл

    Итак. Файл TLD имеет расширение.tld и обычно развертывается внутри каталога WEB-INF в каталоге вашего приложения. Хотя можно разместить и в другом. Если у вас много таких файлов, то для них можно предусмотреть отдельный каталог. Вот наш вариант hello.tld.

    1.0 1.2 Sample Tag Library /SimpleTagLibrary Example of tag for HelloWorld hello students.web.tag.HelloTag empty Hello World Tag example name false true

    < taglib xmlns = "http://java.sun.com/xml/ns/j2ee"

    xmlns : xsi = "http://www.w3.org/2001/XMLSchema-instance"

    xsi : schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"

    version = "2.0" >

    < tlib - version > 1.0 < / tlib - version >

    < jsp - version > 1.2 < / jsp - version >

    < short - name > Sample Tag Library < / short - name >

    < uri > / SimpleTagLibrary < / uri >

    < description >

    Example of tag for HelloWorld

    < / description >

    < tag >

    < name > hello < / name >

    < tag - class > students . web . tag . HelloTag < / tag - class >

    < body - content > empty < / body - content >

    < description >

    Hello World Tag example

    < / description >

    < attribute >

    < name > name < / name >

    < required > false < / required >

    < rtexprvalue > true < / rtexprvalue >

    < / attribute >

    < / tag >

    < / taglib >

    Как вы наверно заметили из описания тэг – это класс HelloTag. Именно он отвечает за отображение информации. Давайте напишем его.

    package students.web.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.tagext.TagSupport; public final class HelloTag extends TagSupport { private String name = null; public int doStartTag() throws JspException { try { if (name == null) { pageContext.getOut().write("Hello, world!"); } else { pageContext.getOut().write("Hello, world! I"m " + name); } } catch (IOException ioe) { throw new JspTagException(ioe.getMessage()); } return SKIP_BODY; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void release() { super.release(); name = null; } }

    package students . web . tag ;

    import java . io . IOException ;

    import javax . servlet . jsp . JspException ;

    import javax . servlet . jsp . JspTagException ;

    import javax . servlet . jsp . tagext . TagSupport ;

    public final class HelloTag extends TagSupport {

    private String name = null ;

    public int doStartTag () throws JspException {

    try {

    if (name == null ) {

    pageContext . getOut () . write ("Hello, world!" ) ;

    } else {

    pageContext . getOut () . write ("Hello, world! I"m " + name ) ;

    } catch (IOException ioe ) {

    throw new JspTagException (ioe . getMessage () ) ;

    return SKIP_BODY ;

    public String getName () {

    return name ;

    public void setName (String name ) {

    this . name = name ;

    public void release () {

    super . release () ;

    name = null ;

    }

    }

    Для сборки нашего сервлета и нового тэга нам потребуется более сложная строка

    javac –cp .;servlet-api.jar;jsp-api.jar students\web\*.java students\web\tag\*.java

    Новую библиотеку jsp-api.jar можно взять там же где и servlet_api.jar – в \common\lib. Теперь, чтобы подключить наш тэг к приложению, необходимо прописать нашу библиотеку в файле web.xml

    Welcome to Students personnel Welcome to Students personnel Hello students.web.HelloWorldServlet Hello /hello http://www.someurl.ru /WEB-INF/hello.tld

    xml version = "1.0" encoding = "ISO-8859-1" ?>

    < web - app >

    < display - name > Welcome to Students personnel < / display - name >