Jsp приложение. Стандартные элементы action. Какие методы жизненного цикла JSP могут быть переопределены

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

Создаем сущности. Создадим в пакете entities класс User, в котором создадим две приватные строковые переменные name и password. Создадим конструкторы (по умолчанию и такой, который бы принимал оба значения), геттеры/сеттеры, переопределим метод toString() на всякий случай, а так же методы equals() и hashCode(). public class User { private String name; private String password; public User() { } public User(String name, String password) { this.name = name; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name="" + name + "\"" + ", password="" + password + "\"" + "}"; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; if (name != null ? !name.equals(user.name) : user.name != null) return false; return password != null ? password.equals(user.password) : user.password == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (password != null ? password.hashCode() : 0); return result; } } Теперь можем приступить к созданию списка пользователей, куда мы будем наших пользователей добавлять, и откуда будем их забирать для отображения. Но есть проблема. Объекты наших сервлетов мы не создаем, их создает за нас томкат. Методы, которые мы переопределяем в них - тоже за нас уже определены и добавить параметр мы не можем. Как же тогда создать общий список, который бы виден был в обоих наших сервлетах? Если мы просто в каждом сервлете создадим свой объект списка - то получится, что добавлять пользователей мы будем в один список, а выводить список пользователей сервлетом ListServlet - совершенно другой. Получается, что нам нужен такой объект, который был бы общим для обоих сервлетов. Если говорить обобщенно, то нам нужен такой объект, который был бы общим для всех классов в нашей программе; единственный объект на всю программу. Надеюсь, вы что-то да слышали про шаблоны проектирования. И возможно для кого-то это первая реальная необходимость использования шаблона в своей программе. Можете поизвращаться и запилить какой-нибудь крутой синглтон, с двойными проверками и синхронизациями (да-да, у нас многопоточное приложение, так как сервлеты томкат запускает в разных потоках), но я буду использовать вариант с ранней инициализацией, так как в данном случае он вполне подходит. Создание модели. Создадим тогда класс (и реализуем в нем шаблон singleton) в пакете model, ну и назовем тоже вполне красочно Model. Создадим в нем приватный объект списка пользователей, и сделаем два метода: один для того, чтоб можно было добавить пользователя, а второй - пусть просто возвращает список строк (имен пользователей). Поскольку наш объект пользователя состоит из имени и пароля - то пароли пользователей мы "светить" не хотели бы, поэтому и возвращать будем только список их имен. public class Model { private static Model instance = new Model(); private List model; public static Model getInstance() { return instance; } private Model() { model = new ArrayList(); } public void add(User user) { model.add(user); } public List list() { return model.stream() .map(User::getName) .collect(Collectors.toList()); } } Немного про mvc. Раз уж вы слышали про singleton, значит возможно слышали и про другой шаблон проектирования - MVC (model-view-controller, или по-русски модель-представление-контроллер, или прям так как и на английском модель-вью-контроллер). Его суть в том, чтобы отделять бизнес-логику от представления. То-есть, отделять код, который определяет что делать от кода, который определяет как отображать . View (представление или просто вьюхи) как-раз и отвечает за то, в каком виде представлять какие-то данные. В нашем случае вьюхи - это наши jsp странички. Именно поэтому я их и положил в папочку с названием views. Модель - это собственно сами данные, с которыми работает программа. В нашем случае это пользователи (список пользователей). Ну а контроллеры - связующее звено между ними. Берут данные из модели и передают их во вьюхи, ну или получают от томката какие-то данные, обрабатывают их и передают модели. Бизнес-логика (то-есть что делать ) должна быть описана в них, а не в модели или во вьюхе. Таким образом, каждый занимается своим делом:
  • модель хранит данные
  • вьюхи рисуют красивое представление данных
  • контроллеры занимаются обработкой данных
Это позволяет всем им быть достаточно простыми и поддерживаемыми. А не монструозной свалкой всего кода в одном классе. MVC подходит не только для веб-программирования, но все-же в этой сфере он встречается очень часто (если не всегда). В нашем случае в качестве контроллеров будут выступать сервлеты. Да это очень поверхностное и даже грубое описание этого паттерна, но эта статья не о шаблонах проектирования, а о том, как сделать простенькое веб-приложение:) Кто хочет узнать больше - гугл знает все ! :) Вернемся к нашим вьюхам. Создаем форму добавления пользователя. Добавим в файл add.jsp форму, состоящую из двух текстовых инпутов (один обычный, другой типа пароль) и кнопки для отправки данных на сервер. Name: Password: Submit Здесь у формы указан атрибут method со значением post. Это говорит о том, что данные из этой формы полетят на сервер в виде POST-запроса. Атрибут action не указан, значит запрос этот полетит по тому же адресу, по которому мы перешли на эту страничку (/add). Таким образом наш сервлет, который привязан к этому адресу, при получении GET-запроса возвращает эту jsp с формой добавления пользователей, а если получит POST-запрос - значит эта форма отправила туда свои данные (которые мы в методе doPost() вытащим из объекта запроса, обработаем и передадим в модель на сохранение). Стоит обратить внимание, что у инпутов здесь указан параметр name (для поля с именем он имеет значение name, а для поля с паролем - pass). Это довольно важный момент. Так как чтобы получить из запроса (внутри сервлета уже) эти данные (имя и пароль которые будут введены) - мы будем использовать именно эти name и pass. Но об этом чуть позже. Сама кнопка отправки данных у меня сделана снова же в виде button, а не инпутом, как это обычно принято. Не знаю насколько такой вариант универсален, но у меня в хроме работает:) Обработка POST-запроса сервлетом. Вернемся к сервлету AddServlet. Мы уже знаем, что чтобы наш сервлет умел "ловить" GET-запросы - мы переопределили метод doGet() из класса HttpServlet. Чтобы научить наш сервлет ловить еще и POST-звапросы - мы переопределяем еще и метод doPost(). Он получает аналогичные объекты запроса и ответа от томката, с которыми мы и будем работать. Для начала вытащим из запроса параметры name и pass, которые отправила форма (если вы их в форме назвали по-другому - тогда именно те названия и пишете). После чего создадим объект нашего пользователя, используя полученные данные. Потом получим объект модели и добавим созданного пользователя в модель. @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); } Передача данных во вьюху. Теперь перейдем к сервлету ListServlet. У нас тут уже реализован метод doGet(), который просто передает управление во вьюху list.jsp. Если у вас этого еще нет - сделайте по аналогии с таким же методом из сервлета AddServlet. Теперь было бы неплохо получить из модели список имен пользователей и передать их во вьюху, которая их там получит и красивенько отобразит. Для этого воспользуемся снова же объектом запроса, который мы получили от томката. К этому объекту мы можем добавить атрибут, дав ему какое-то имя ну и собственно сам объект, который бы мы хотели передать во вьюху. Благодаря тому, что при передаче процесса выполнения из сервлета во вьюху мы передаем туда эти же объекты запроса и ответа, что получил сам сервлет, то и добавив наш список имен к объекту запроса мы потом из этого объекта запроса во вьюхе сможем наш список имен пользователей и получить. С классом ListServlet мы закончили, поэтому привожу код всего класса package app.servlets; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; public class ListServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Model model = Model.getInstance(); List names = model.list(); req.setAttribute("userNames", names); RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp"); requestDispatcher.forward(req, resp); } } Выполнение java-кода в jsp файлах. Теперь перейдем к файлу list.jsp. Этот файл выполнится только когда ListServlet передаст сюда процесс выполнения. Кроме того, мы в том сервлете уже подготовили список имен пользователей из модели и передали сюда в объекте запроса. Имея список имен мы можем пробежаться по нему циклом for и вывести каждое имя. Как я уже говорил, jsp файлы могут выполнять java-кода (в принципе, этим и отличаются от статичных html страничек). Для того, чтобы выполнить какой-то код - достаточно поставить в нужном нам месте конструкцию Внутри такой конструкции мы получаем доступ к нескольким переменным: request - наш объект запроса, который мы передали из сервлета, где он назывался просто req responce - объект ответа, в сервлете назывался resp out - объект типа JspWriter (наследуется от обычного Writer), при помощи которого можем "писать" что-либо прямо в саму html страничку. Запись out.println("Hello world!") очень похожа на запись System.out.println("Hello world!"), но не стоит их путать! out.println() "пишет" в html страничку, а System.out.println - в системный вывод. Если вызвать внутри раздела с джава кодом jsp метод System.out.println() - то результаты увидите в консоли томката, а не на страничке, как возможно хотелось бы:) Про другие доступные объекты внутри jsp можно поискать . Используя объект request мы можем получить список имен, который передавали из сервлета (мы прикрепили соответствующий атрибут к этому объекту), а используя объект out - можем вывести эти имена. Сделаем это пока просто в виде html списка: Если же хотим выводить список только в том случае, когда есть пользователи, а иначе выводить предупреждение, что пользователей пока нет - можем немного переписать этот участок: Теперь, когда мы умеем передавать данные из сервлетов во вьюхи - можем немного улучшить наш AddServlet, чтобы выводилось уведомление об успешном добавлении пользователя. Для этого в методе doPost() после того, как добавили нового пользователя в модель - можем добавить имя этого пользователя в атрибуты объекта req и передать управление обратно во вьюху add.jsp. А в ней уже сделать участок с джава кодом, где проверять есть ли такой атрибут в запросе, и если да - то выводить сообщение, что пользователь успешно добавлен. После этих изменений полный код сервлета AddServlet будет выглядеть примерно так: package app.servlets; import app.entities.User; import app.model.Model; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class AddServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp"); requestDispatcher.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("name"); String password = req.getParameter("pass"); User user = new User(name, password); Model model = Model.getInstance(); model.add(user); req.setAttribute("userName", name); doGet(req, resp); } } Тут в конце метода doPost() мы устанавливаем атрибут с именем добавленного в модель пользователя, после чего вызываем метод doGet(), в который передаем текущие запрос и ответ. А метод doGet() уже передает управление во вьюху, куда и отправляет объект запроса с прикрепленным именем добавленного пользователя в качестве атрибута. Осталось подправить саму add.jsp чтобы она выводила такое уведомление, если присутствует такой атрибут. Конечный вариант add.jsp Add new user Super app! Add user Name: Password: Submit Back to main Тело страницы состоит из div-a с шапкой, после чего div-контейнер для контента, в нем проверка существует ли атрибут с именем пользователя, потом div с формой добавления пользователей, ну и в конце футер с кнопкой возврата на главную страницу. Может показаться, что слишком много div-ов, но мы их потом используем, когда добавим стилей:) Ну и конечный вариант list.jsp Users Super app! Users Back to main Таким образом, мы имеем полностью рабочее веб приложение, которое умеет хранить и добавлять пользователей, а так же выводить список их имен. Осталось лишь приукрасить... :) Добавление стилей. Используем фреймворк W3.CSS. В данный момент наше приложение рабочее, но абсолютно вырвиглазное:) Нужно добавить фон, цвета текста и кнопок, стилизировать списки, сделать выравнивание, добавить отступов, в общем много чего. Если писать стили вручную - это может занять много времени и нервов. Поэтому я предлагаю воспользоваться CSS фреймворком W3.CSS . В нем уже есть готовые классы со стилями, осталось только расставить в нужных местах те css классы, которые мы хотим в этих местах применить. Для того, чтобы добавить их к себе на страницы во-первых нам надо подключить файл со стилями. Это можно сделать двумя способами: 1. пройтись по нашим страницам и в разделе head вставить прямую ссылку на файл со стилями Такой вариант подходит, если у вас постоянное подключение к интернету. Тогда при открытии ваших страниц на локальном сервере - стили подтянутся из интернета. 2. Если же вы хотите иметь все стили у себя локально и не быть зависимым от интернет-соединения - можете просто скачать файл со стилями и поместить его где-нибудь внутри папочки web (например web/styles/w3.css), после чего пройтись по всем нашим страничкам (index.html, add.jsp, list.jsp) и вписать внутри раздела head ссылку на этот файл со стилями После этого просто пройтись по тегам и подописывать им те стили, которые вам понравятся. Я не буду останавливаться на этом подробно, а сразу дам свои готовые варианты трех моих файлов с раставленными классами стилей. index.html Super app! Super app! List users Add user add.jsp Add new user Super app! Add user Name: Password: Submit Back to main list.jsp Users list Super app! Users Back to main Вот и все:) Если у вас остались какие-то вопросы или есть какие-то замечания, или же наоборот что-то не получается - оставьте комментарий. Ну и парочку скриншотов приложу что из этого всего получилось.

И напоследок. Если будет желание попрактиковаться с этим проектом - можете попробовать:
  • сделать сервлет и jsp для удаления пользователя и еще пару для изменения/редактирования существующего пользователя. Получится настоящее CrUD веб приложение:) на сервлетах))
  • заменить список (List) на работу с базой данных, чтоб добавленные пользователи не пропадали после перезапуска сервера:)
Удачи!

Вопросы и ответы на собеседование по теме Java Server Pages (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 состоит из нескольких фаз:

  • Translation – JSP контейнер проверяет код JSP страницы, парсит ее для создания кода сервлета. К примеру, в Tomcat вы можете найти классы сервлетов в директории TOMCAT/work/Catalina/localhost/WEBAPP/org/apache/jsp . Если страница JSP называется home.jsp, то созданный сервлет обычно будет иметь имя home_jsp и имя файла — home_jsp.java .
  • Compilation – JSP контейнер компилирует исходный код jsp класса и создает класс на этой фазе.
  • – контейнер загружает классы в память на этой фазе.
  • Instantiation – внедрение конструкторов без параметров созданных классов для инициализации в памяти классов.
  • Initialization – в контейнере вызывается init метод объекта JSP класса и инициализируется конфигурация сервлета с init параметрами, которые указаны в дескрипторе развертывания (web.xml ). После этой фазы JSP способен обрабатывать запросы клиентов.Обычно эти фазы происходят после первого запроса клиента (т.е. ленивая загрузка), но можно настроить загрузку и инициализацию JSP на старте приложения по аналогии с сервлетами.
  • Request Processing – длительный жизненный цикл обработки запросов клиента JSP страницей. Обработка является многопоточной и аналогична сервлетам — для каждого запроса создается новая нить, создаются объекты ServletRequest и ServletResponse и происходит внедрение сервис методов JSP.
  • 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() метод переопределяется, чтобы освободить общие ресурсы на фазе уничтожения.

    5. Как можно предотвратить прямой доступ к JSP странице из браузера?

    Директория WEB-INF не имеет прямого доступа из веб приложения. Поэтому мы можем положить JSP страницы внутри этой папки и тем самым запретить доступ к странице из браузера. Однако в этом случае необходимо настраивать дескриптор развертывания наподобие сервлетов. Простая конфигурация дескриптора web.xml показана ниже.

    Test /WEB-INF/test.jsp test Test Value Test /Test.do

    < servlet - name > Test < / servlet - name >

    < jsp - file > / WEB - INF / test . jsp < / jsp - file >

    < init - param >

    < param - name > test < / param - name >

    < param - value > Test Value < / param - value >

    < / init - param >

    < / servlet >

    < servlet - mapping >

    < servlet - name > Test < / servlet - name >

    < url - pattern > / Test . do < / url - pattern >

    < / servlet - mapping >

    6. Как закомментировать код в jsp?

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

    • HTML комментарии — . Такие комментарии будут видны клиенту при просмотре кода страницы.
    • JSP комментарии — . Такие комментарии создаются в созданном сервлете и не посылаются клиенту. Для любых комментариев по коду или отладочной информации необходимо использовать этот тип комментариев.
    7. Объясните Scriptlet, Expression и Declaration в JSP.

    Scriptlet, Expression и Declaration — скриптовые элементы внутри JSP страницы, которые могут выполнять Java код. Скриптлеты задаются тегом . Любой код внутри этих тегов будет передан _jspService() методу.

    Date d = new Date () ;

    System . out . println ("Current Date=" + d ) ;

    Достаточно часто требуется показать динамическую информацию с использованием метода out.print() . Для этого существует язык выражений (expression), который записывается как . Например, выражение может быть переписано с помощью JSP выражения . Отметьте, что всё, что находится внутри тегов будет передано в out.print() метод. Так же обратите внимание, что скриптлеты могут содержать несколько java выражений, разделенных точкой с запятой, в то время как выражения не должны заканчиваться на точку с запятой.

    JSP Declaration используется для объявления методов и переменных класса сервлета. Declaration записываются с помощью тега , например — .

    8. Какие неявные, внутренние объекты и методы есть на jsp странице?

    JSP implicit objects (неявные объекты) создаются контейнером при конвертации JSP страницы в код сервлета для помощи разработчикам. Эти объекты можно использовать напрямую в скриптлетах для передачи информации в сервис методы, однако мы не можем использовать неявные объекты в JSP Declaration, т.к. такой код пойдет на уровень класса.
    Существует 9 видов неявных объектов, которые можно использовать прямо на JSP странице. Семь из них объявлены как локальные переменные в начале _jspService() метода, а два оставшихся могут быть использованы как аргументы метода _jspService() .

  • out Object
  • request Object
  • response Object
  • config Object
  • application Object
  • session Object
  • pageContext Object
  • page Object
  • exception Object
  • Index JSP Page Hi There Current Time is:

    Request User-Agent:

    User init param value:

    User context param value:

    User Session ID:

    PageContext attribute: {Name="Test",Value=""}

    Generated Servlet Name:

    < ! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >

    < meta http - equiv = "Content-Type" content = "text/html; charset=US-ASCII" >

    Index JSP Page < / title >

    < / head >

    Current Time is < / strong > :

    Request User - Agent < / strong > :

    User init param value < / strong > :

    User context param value < / strong > :

    User Session ID < / strong > :

    PageContext attribute < / strong > : { Name = "Test" , Value = " " }

    Generated Servlet Name < / strong > :

    < / body >

    < / html >

    9. Почему неявные объекты не доступны в обычной JSP странице?

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

    10. Что вы знаете о PageContext и какие преимущества его использования?

    Неявный объект JSP pageContext является экземпляром реализации абстрактного класса javax.servlet.jsp.PageContext . Мы можем использовать объект pageContext для получения и установки атрибутов с различной областью видимости и для проброса запросов к другому ресурсу. Этот объект так же обладает ссылкой на другой неявный объект. Это единственный объект, который представлен в JSP implicit objects и JSP EL implicit objects.

    11. Как сконфигурировать init параметры для JSP?

    Мы можем задать параметры инициализации для JSP аналогично сервлетам в web.xml файле. Мы должны сконфигурировать init параметры JSP с элементами servlet и servlet-mapping. Единственным отличием будет указание местонахождения JSP страницы.

    JSP страницы в основном используются для целей отображения представления, а вся бизнес логика и модели должны быть реализованы в сервлетах или классах моделях. Мы должны передавать параметры к JSP странице через атрибуты и затем использовать их для создания HTML ответа на JSP странице. Большая часть JSP содержит HTML код и для того, чтобы помочь дизайнерам понять код JSP страницы и разрабатывать их, предоставляют элементы action, JSP EL, JSP Standart Tag Library. Именно эти элементы необходимо использовать вместо скриптлетов для создания моста между JSP HTML и JSP java частями.

    13. Можем ли мы определить класс внутри JSP страницы?

    Определить класс внутри JSP страницы можно, но это считается плохой практикой. Это можно сделать так

    < jsp - property - group >

    < url - pattern > * . jsp < / url - pattern >

    < scripting - invalid > true < / scripting - invalid >

    < / jsp - property - group >

    < / jsp - config >

    16. Что вы знаете о jsp тегах? Объясните как вы понимаете Action tag и JSP Action Elements.

    JSP элементы или теги action предоставляют полезную функциональность для работы с Java Bean, вложения ресурсов, проброса запроса и создания динамических XML элементов. Элементы jsp action всегда начинаются с записи jsp: и мы можем использовать их прямо внутри страницы JSP без необходимости подключения библиотек или других настроек.

    Наиболее часто используемыми элементами action являются: jsp:useBean , jsp:getProperty , jsp:setProperty , jsp:include , jsp:forward .

    17. Какая разница между директивой include и jsp:include action?

    Разница между директивой JSP include и jsp:include action заключается в том, что для директивы include, контент для другого ресурса будет добавлен в созданный сервлет на этапе трансляции JSP (фаза Translation), в то время как jsp:include action работает в рантайме.
    Другое отличие JSP include action в том, что мы можем передать параметры для вложения с помощью команды jsp:params , в то время как директива jsp include не имеет возможности передавать параметры.
    Использовать директиву JSP include необходимо для статических ресурсов вроде header, footer, image file для повышения производительности. Если же нам необходима динамика, передача параметров для обработки, то необходимо использовать тег jsp:include action.

    18. Что вы знаете о языке выражений jsp (JSP Expression Language – EL)?

    В большинстве случаев мы используем JSP для целей просмотра, а вся бизнес-логика присутствует в сервлете или классах модели. После получения запроса клиента он обрабатывается в сервлете, а затем добавляем атрибуты в request/session/context scope, которые должны быть извлечены в JSP коде. Для создания ответа представлений так же используются request , headers , cookies и init параметры.
    Мы можем использовать скриптлеты в JSP выражениях для получения атрибутов и параметров в JSP с Java кодом и использовать его для представлений. Проблема заключается в том, что веб дизайнеры обычно не знают java код, и именно поэтому в JSP 2.0 введен язык выражений (EL), через который мы можем получить атрибуты и параметры с помощью тегов HTML.
    Синтаксис expression language выглядит как $ {имя} , и мы можем использовать EL неявные объекты и операторы языка выражений для извлечения атрибутов из разных scopes и использовать их в JSP странице.

    19. Назовите неявные, внутренние объекты JSP EL и их отличия от объектов jsp.

    Язык выражений JSP предоставляет множество неявных объектов, которые можно использовать для получения атрибутов в различных областях видимости (scopes) и для значений параметров. Важно отметить, что они отличаются от неявных объектов JSP и содержат атрибуты в заданной области видимости. Наиболее часто использующийся implicit object в JSP EL и JSP page — это объект pageContext. Ниже представлена таблица неявных объектов JSP EL.

    JSP EL Implicit Objects Type Description
    pageScope Map Карта атрибутов для page scope.
    requestScope Map Используется для получения атрибутов в request scope.
    sessionScope Map Используется для получения атрибутов из session scope.
    applicationScope Map Используется для получения атрибутов из application scope.
    param Map Используется для получения значения параметра request, возвращает одно значение.
    paramValues Map Используется для получения значений параметров запроса в массиве. Удобно для параметров запроса, который содержит множество значений.
    header Map Используется для получения информации о request header.
    headerValues Map Используется для получения значений header values в массиве.
    cookie Map Используется для получения значения cookie в JSP
    initParam Map Используется для получения параметров context init. Мы не можем использовать их для параметров инициализации сервлета (servlet init params).
    pageContext pageContext Такой же как и объект JSP implicit pageContext. Используется для получения request, session references и т.д. К примеру, получение имени request HTTP Method.
    20. Как узнать имя http метода используя JSP EL?

    Вот так: ${pageContext.request.method} .

    21. Что такое JSTL (Jsp Standard tag library)?

    Стандартная библиотека тегов JSP (англ. JavaServer Pages Standard Tag Library, JSTL) - расширение спецификации JSP, добавляющее библиотеку JSP тегов для общих нужд, таких как разбор XML данных, условная обработка, создание циклов и поддержка интернационализации. JSTL - конечный результат JSR 52, разработанного в рамках процесса сообщества Java.

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

    jstl jstl 1.2 taglibs standard 1.1.2

    jstl < / groupId >

    jstl < / artifactId >

    1.2 < / version >

    < / dependency >

    taglibs < / groupId >

    standard < / artifactId >

    1.1.2 < / version >

    < / dependency >

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

    22. На какие категории можно разделить JSTL теги, приведите примеры.

    JSTL теги разделяются на пять категорий согласно их функциональности:

  • Core Tags – Core tags предоставляют возможности итерации, обработки исключений, url, forward и redirect response и т.д.
  • Formatting и Localization Tags – предоставляют возможности по форматированию Numbers, Dates и поддержки i18n локализации и resource bundles.
  • SQL Tags – JSTL SQL Tags поддержка работы с базами данных вроде MySQL, Oracle и т.д.
  • XML Tags – используются для работы с XML документами. Например для парсинга XML, преобразования данных XML и выполнения выражений XPath.
  • JSTL Functions Tags – предоставляет набор функций, которые позволяют выполнять различные операции со строками и т.п.. Например по конкатенации или разбиению строк.
  • 23. Что вы знаете о написании пользовательских jsp тегов?

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

    • JSP Custom Tag Handler
    • Создание файла Tag Library Descriptor (TLD)
    • Deployment Descriptor конфигурацию для TLD
    24. Приведите пример использования собственных тегов.

    Например нам необходимо отформатировать в каком-либо стиле очень длинное число. Для этого можно использовать собственный тег вроде:

    < mytags : formatNumber number = "123456.789" format = "#,###.00" / >

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

    25. Почему не нужно конфигурировать стандартные JSP теги в web.xml?

    Нам не нужно настраивать стандартные теги JSP в web.xml, потому что TLD файлы уже находятся внутри каталога META-INF в JSTL jar файлах. Когда контейнер загружает веб-приложение и находит TLD файлы в директории META-INF в JAR файле, то он автоматически настраивает их для непосредственного использования на JSP страницах. Остается только задать пространство имен на jsp странице.

    26. Как можно обработать ошибки jsp страниц?

    Для обработки исключений выброшенных на jsp странице необходимо всего лишь задать страницу ошибки. Для создания страницы ошибки JSP мы должны установить значение page directive attribute isErrorPage в значение true. Тогда мы получим доступ к неявным объектам исключений в JSP и сможем передавать собственные сообщение об ошибках клиенту (обычно более информативных).

    Настройка дескриптора развертывания выглядит так.

    404 /error.jsp java.lang.Throwable /error.jsp

    < error - page >

    < error - code > 404 < / error - code >

    / error . jsp < / location >

    < / error - page >

    < error - page >

    < exception - type > java . lang . Throwable < / exception - type >

    / error . jsp < / location >

    < / error - page >

    27. Как происходит обработка ошибок с помощью jstl?

    Перехватывать исключения и обрабатывать их в служебных методах класса можно с помощью JSTL Core Tags c:catch и c:if . Тег c:catch перехватывает исключение и обертывает его в переменную exception, которую мы можем обработать в теге c:if .

    Exception is: ${exception}
    Exception Message: ${exception.message}

    < c : catch var = "exception" >

    < / c : catch >

    < c : if test = "${exception ne null}" >

    Exception is : $ { exception } < br / >

    Exception Message : $ { exception . message } < / p >

    < / c : if >

    Обратите внимание что используется язык выражений JSP EL в теге c:if .

    28. Как сделать «новую линию в HTML» в JSP?

    Для переноса строки можно использовать тег c:out и атрибут escapeXml для отключения обработки HTML элементов и браузер получит следующий код как строку (и обработает элемент
    как требуется).

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

    getServletContext () . getRequestDispatcher ("/hello.jsp" ) . forward (req , resp ) ;

    Самая интересная строка (она же пока и единственная) позволяет нам получить ресурс (в нашем случае это hello.jsp) и передать этому ресурсу наши данные. В данном случае мы ничего не меняли и не добавляли. Теперь давайте посмотрим на файл hello.jsp, который должен представить пользователю некую страницу. В данном случае она не очень сложная, но все-таки мы остановимся на ней подробнее.

    Hello World Sample Hello, world ! Hello, world ! I"m

    < html >

    < head >

    < title >

    Hello World Sample

    < / title >

    < / head >

    < body >

    < h1 >

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

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

    Hello , world !

    Похожие публикации