<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Moradan</id>
		<title>Linuxformat - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Moradan"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:Contributions/Moradan"/>
		<updated>2026-05-13T11:08:00Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF91:Java_EE</id>
		<title>LXF91:Java EE</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF91:Java_EE"/>
				<updated>2009-08-04T07:40:09Z</updated>
		
		<summary type="html">&lt;p&gt;Moradan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Цикл/Java EE}}&lt;br /&gt;
[[Категория:Учебники]]&lt;br /&gt;
__TOC__&lt;br /&gt;
:В прошлый раз вы, под чутким руководством '''Александра''', разобрались с JSP и переписали &amp;quot;Телефонную книгу&amp;quot; с учетом этой технологии. Сегодня мы двинемся дальше и поговорим об авторизации, сессиях, фильтрах и использовании разделяемых объектов в web-приложениях.&lt;br /&gt;
&lt;br /&gt;
:''{{oncolor||red|ЧАСТЬ 3}} Каждый линуксоид знает, что система уровня предприятия должна обеспечивать разграничение доступа. '''Антон Черноусов''' расскажет, что может предложить здесь Java EE.&lt;br /&gt;
[[Media:AddressBook2.tar.bz2|Скачать исходный код примера]]&lt;br /&gt;
&lt;br /&gt;
==Процесс передачи информации==&lt;br /&gt;
Давайте рассмотрим стандартную ситуацию: пользователь вызывает различные страницы одного web-приложения. Если бы этот &amp;quot;диалог&amp;quot; происходил по телефону, он был бы примерно таким:&lt;br /&gt;
*'''Пользователь (набирает номер): Алло, это приложение?'''&lt;br /&gt;
*Приложение: Да, это приложение.&lt;br /&gt;
*(Пользователь кладет трубку)&lt;br /&gt;
*'''Пользователь (набирает номер): Меня зовут Георг.'''&lt;br /&gt;
*Приложение: Да, Георг, мы вас внимательно слушаем.&lt;br /&gt;
*(Пользователь кладет трубку)&lt;br /&gt;
*'''Пользователь (набирает номер): Дайте мне, пожалуйста, всю информацию.'''&lt;br /&gt;
*Приложение: Возьмите...&lt;br /&gt;
Отметим, что после каждого обмена репликами пользователь кладет трубку, разрывая соединение - именно таким образом в большинстве случаев и происходит обмен данными между браузером пользователя и сервером, на котором работает web-приложение. Возникает резонный вопрос: как передавать информацию между соединениями, открываемые в рамках одной сессии? Для этого могут использоваться самые различные методы:&lt;br /&gt;
*перезапись URL;&lt;br /&gt;
*скрытые поля;&lt;br /&gt;
*cookie;&lt;br /&gt;
*сессионный объект.&lt;br /&gt;
Из всех представленных методов наиболее простым и в тоже время мощным является сессионный объект (Session), реализованный в Java посредством интерфейса {{oncolor||red|javax.servlet.http.Session}}.&lt;br /&gt;
Ранее, чтобы получить данные от пользователя или обеспечить возможность их транспортировки внутри приложения, мы использовали объект типа &lt;br /&gt;
{{oncolor||red|HttpServletRequest}}. Основное отличие {{oncolor||red|HttpSession}} заключается во времени жизни, схематично изображенном на '''Рис.1'''. Объект типа {{oncolor||red|HttpServletRequest}} предназначен для передачи запроса (и необходимых данных) от браузера к web-приложению и существует только между запросом и ответом, в то время как объект {{oncolor||red|HttpSession}} обеспечивает средства для хранения и доступа к данным пользователя на протяжениии всего периода работы с приложением.&lt;br /&gt;
)(Рис.1) Время жизни объектов HttpServletRequest и HttpSession.&lt;br /&gt;
Следует, однако, иметь в виду, что отследить момент, когда пользователь перестает работать с приложением, не всегда возможно. Поэтому в настройках сервера устанавливается некоторое предельное время существования объекта {{oncolor||red|HttpSession}} после получения последнего запроса.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF91_javaee1.png|Рис. 1]]&lt;br /&gt;
&lt;br /&gt;
'''Время жизни объектов ''HttpServletRequest'' и ''HttpSession'''''&lt;br /&gt;
&lt;br /&gt;
==Сессия==&lt;br /&gt;
Объект session в JSP является предопределеным, то есть с ним можно сразу же начинать работать. Чтобы создать сессионный объект в сервлете, воспользуемся следующим методом:&lt;br /&gt;
&lt;br /&gt;
 HttpSession session = aRequest.getSession(true);&lt;br /&gt;
&lt;br /&gt;
Здесь '''aRequest''' – это экземпляр объекта '''HttpServletRequest''', то есть&lt;br /&gt;
запрос переданный сервлету.&lt;br /&gt;
&lt;br /&gt;
Классы, реализующие интерфейс '''HttpSession''', имеют два замечательных метода: '''setAttribute(String, Object)''' и '''getAttribute(String)'''. Метод&lt;br /&gt;
'''setAttribute(String, Object)''' применяется для добавления объекта в сессию, а '''getAttribute(String)''' – для извлечения объекта из нее. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
 session.setAttribute(“sameKey”,sameObject);&lt;br /&gt;
 SameObject aObject = (SameObject) session.getAttribute(“sameKey”);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Фактически, объект '''session''' – это таблица '''Hashtable''', в которой можно хранить любое количество пар типа «ключ – объект». При использовании сессионного объекта данные приложения не отправляются&lt;br /&gt;
пользователю так, как это происходит с cookie. Сессионный объект&lt;br /&gt;
хранится на сервере персонально для каждого клиента. Сервер различает сессии с помощью маркера, который передается пользователю.&lt;br /&gt;
Маркер хранится в cookies браузера до конца сессии, что накладывает&lt;br /&gt;
некоторые ограничения на клиентское рабочее место (использование&lt;br /&gt;
cookies для вашего приложения должно быть разрешено). В этом можно легко убедиться, просмотрев сохраненные cookies в вашем любимом браузере.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF91_javaee2.png|Рис. 2]]&lt;br /&gt;
&lt;br /&gt;
'''Маркер сессии. Герои романа «''Лабиринт отражений''» пытались повесить друг другу маркер под видом невинного поцелуя, а наше web-приложение действует еще хитрее и незаметнее.'''&lt;br /&gt;
&lt;br /&gt;
==Авторизация==&lt;br /&gt;
&lt;br /&gt;
Логично предположить, что чаще всего сессии применяются там, где&lt;br /&gt;
необходимо авторизовать пользователя и предоставлять доступ к&lt;br /&gt;
определенным функциям приложения только при наличии соответствующих привилегий. Давайте обратимся к нашей телефонной книге:&lt;br /&gt;
ее просмотр разрешен всем желающим, а для добавления нового телефона, редактирования и удаления записи необходима авторизация.&lt;br /&gt;
&lt;br /&gt;
Давайте создадим JSP-страницу '''auth.jsp''', которая будет запрашивать у пользователя имя и пароль. Сохраните файл в каталоге '''jsps''' и введите в него следующий текст:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
&amp;lt;span style=”color: green;”&amp;gt;&amp;lt;%=request.getAttribute(“message”)%&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;form action=”&amp;lt;%=request.getContextPath()%&amp;gt;/auth” method=”post”&amp;gt;&lt;br /&gt;
        &amp;lt;table&amp;gt;&lt;br /&gt;
               &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Логин: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=”text” name=”login”/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
               &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Пароль: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;br /&gt;
                         &amp;lt;input type=”password” name=”password”/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
               &amp;lt;tr&amp;gt;&amp;lt;td colspan=”2” align=”center”&amp;gt;&lt;br /&gt;
                        &amp;lt;input type=”submit” value=”Авторизоваться”/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
           &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/form&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Легко видеть, что в форме имеется два поля ввода и одна кнопка.&lt;br /&gt;
Заметим также, что поле для ввода пароля имеет тип '''password''', так что&lt;br /&gt;
вместо нажатых клавиш в окне браузера будут отображаться до боли&lt;br /&gt;
знакомые «звездочки» ('''‘*’''').&lt;br /&gt;
&lt;br /&gt;
Теперь внесем изменения в '''AddressBookServlet''': расширим ветвление в методе '''handle''' следующим образом:&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
 }else if (“/auth”.equals(target)) {&lt;br /&gt;
           handleAuth(aRequest, aResponse);&lt;br /&gt;
       }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дело за малым – осталось написать метод '''handleAuth(aRequest,aResponse)''', который и будет обрабатывать данные, введенные в форму, то есть производить авторизацию пользователя.&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
    private void handleAuth(HttpServletRequest aRequest,&lt;br /&gt;
               HttpServletResponse aResponse) throws IOException,&lt;br /&gt;
 ServletException {&lt;br /&gt;
       String login = aRequest.getParameter(“login”);&lt;br /&gt;
       String password = aRequest.getParameter(“password”);&lt;br /&gt;
       if ((login != null) &amp;amp;&amp;amp; (password != null)) {&lt;br /&gt;
           // here is auth process&lt;br /&gt;
           if ((login.equals(“user”)) &amp;amp;&amp;amp; (password.equals(“userPass”))) {&lt;br /&gt;
               //here is success auth&lt;br /&gt;
               HttpSession session = aRequest.getSession(true);&lt;br /&gt;
               session.setAttribute(“auth”,aRequest.getParameter(“login”));&lt;br /&gt;
               aRequest.setAttribute(“message”, null);&lt;br /&gt;
               outputPage(“index.jsp”, aRequest, aResponse);&lt;br /&gt;
           } else {&lt;br /&gt;
               //here is failed auth&lt;br /&gt;
               aRequest.setAttribute(“message”,&lt;br /&gt;
                            “Неверный логин или пароль, повторите ввод&lt;br /&gt;
 данных”);&lt;br /&gt;
               outputPage(“auth.jsp”, aRequest, aResponse);&lt;br /&gt;
           }&lt;br /&gt;
       } else {&lt;br /&gt;
           //here is no data to auth&lt;br /&gt;
           aRequest.setAttribute(“message”,&lt;br /&gt;
                        “Логин и пароль не могут быть пустыми, повторите&lt;br /&gt;
 ввод данных”);&lt;br /&gt;
           outputPage(“auth.jsp”, aRequest, aResponse);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы не усложнять приложение, мы используем простейший&lt;br /&gt;
способ авторизации – имя пользователя и пароль жестко зашиты в&lt;br /&gt;
теле метода. С точки зрения безопасности и масштабируемости лучше&lt;br /&gt;
использовать для хранения этих данных БД.&lt;br /&gt;
&lt;br /&gt;
В случае удачной авторизации мы помещаем имя пользователя в&lt;br /&gt;
объект '''session''' и перенаправляем его на главную страницу. Если же&lt;br /&gt;
авторизация не удалась (введено неверное имя пользователя и/или&lt;br /&gt;
пароль), пользователю будет предложено повторить попытку.&lt;br /&gt;
&lt;br /&gt;
Таким образом, если авторизация прошла успешно, в сессии пользователя будет сохранен объект, содержащий его имя. Используя этот&lt;br /&gt;
факт, можно изменить '''index.jsp''' и спрятать ссылку на добавление нового телефона от посторонних глаз:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
        &amp;lt;%String name = (String)session.getAttribute(“auth”);&lt;br /&gt;
         if (name != null){ %&amp;gt;&lt;br /&gt;
              &amp;lt;p&amp;gt;Вы авторизованны как: &amp;lt;%=name%&amp;gt; &amp;lt;/p&amp;gt;&lt;br /&gt;
              &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/add”&amp;gt;Добавить&lt;br /&gt;
 запись&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
         &amp;lt;%} else {%&amp;gt;&lt;br /&gt;
             &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/auth”&amp;gt;&lt;br /&gt;
 Авторизоваться&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
         &amp;lt;%} %&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Мы приветствуем пользователя, используя значение атрибута '''auth'''&lt;br /&gt;
и предоставляем ему доступ к функции добавления нового контакта.&lt;br /&gt;
Чтобы спрятать удаление и редактирование записей от неавторизованного пользователя, необходимо внести аналогичные изменения в&lt;br /&gt;
файл '''view.jsp'''.&lt;br /&gt;
&lt;br /&gt;
==Фильтры==&lt;br /&gt;
&lt;br /&gt;
Наше приложение, к сожалению, страдает проблемами безопасности:&lt;br /&gt;
злонамеренный пользователь может обойти процедуру авторизации,&lt;br /&gt;
обратившись к функциям редактирования/удаления напрямую, по&lt;br /&gt;
адресу '''request.getContextPath() + действие (/add; /edit; /remove)'''; можно также непосредственно вызывать JSP-страницы, расположенные в каталоге '''/jsps''' – нужно только узнать их имена.&lt;br /&gt;
&lt;br /&gt;
Что же делать? Проверять, авторизован ли пользователь перед&lt;br /&gt;
выполнением привилегированного действия? Это неудобно – если&lt;br /&gt;
количество JSP будет расти, это заставит вас написать много строк&lt;br /&gt;
однотипного кода, поддержание которых будет отнимать ваше драгоценное время. Мы пойдем другим путем и воспользуемся так называемыми фильтрами.&lt;br /&gt;
&lt;br /&gt;
Схема работы фильтров представлена на Рис. 3. Если для адреса,&lt;br /&gt;
на который отображен сервлет, осуществляется фильтрация, запрос&lt;br /&gt;
будет передан сервлету только после того, как пройдет через каждый&lt;br /&gt;
установленный фильтр.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF91_javaee3.png|Рис. 3]]&lt;br /&gt;
&lt;br /&gt;
'''Схема прохождения запроса через фильтры.'''&lt;br /&gt;
&lt;br /&gt;
На самом деле, фильтр представляет из себя обыкновенный Java-&lt;br /&gt;
класс, реализующий интерфейс '''javax.servlet.Filter'''. Например:&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
 public class FirstFilter implements Filter {&lt;br /&gt;
   private FilterConfig filterConfig;&lt;br /&gt;
   public void init(FilterConfig filterConfig) throws ServletException {&lt;br /&gt;
       System.out.println(“Filter init”);&lt;br /&gt;
       this.filterConfig = filterConfig;&lt;br /&gt;
   }&lt;br /&gt;
   public void doFilter(ServletRequest aRequest, ServletResponse&lt;br /&gt;
 aResponse, FilterChain filterChain)&lt;br /&gt;
   throws IOException, ServletException {&lt;br /&gt;
       System.out.println(“Filter used”);&lt;br /&gt;
       filterChain.doFilter(aRequest, aResponse);&lt;br /&gt;
   }&lt;br /&gt;
   public void destroy() {&lt;br /&gt;
       System.out.println(“Filter dead”);&lt;br /&gt;
       this.filterConfig = null;&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Реализовав всего три метода: '''init''' (инициализация фильтра в&lt;br /&gt;
момент старта приложения), '''destroy''' (освобождение ресурсов перед&lt;br /&gt;
завершением работы приложения) и '''doFilter''' (собственно метод, выполняющий фильтрацию), вы получаете класс, способный существенным образом повлиять на работу вашего приложения.&lt;br /&gt;
&lt;br /&gt;
Обратите внимание, что в приведенном выше примере метод&lt;br /&gt;
'''doFilter''' заканчивается вызовом метода '''doFilter(aRequest, aResponse)'''&lt;br /&gt;
объекта '''filterChain''' – это обеспечивает вызов следующего фильтра в&lt;br /&gt;
цепочке (естественно, если фильтров несколько). Если фильтров больше нет, то управление будет передано следующему ресурсу, например, сервлету.&lt;br /&gt;
&lt;br /&gt;
Остановимся подробнее на методе '''init''', а точнее на объекте, реализующем интерфейс '''FilterConfig'''. Этот объект имеет четыре замечательных метода:&lt;br /&gt;
* '''getFilterName()''' – возвращает имя фильтра;&lt;br /&gt;
* '''getInitParameterNames()''' – возвращает объект '''Enumeration''', который содержит в своем теле имена параметров текущего фильтра;&lt;br /&gt;
* '''getInitParameter(String)''' – возвращает значение параметра, имя которого было передано в качестве аргумента;&lt;br /&gt;
* '''getServletContext()''' – возвращает объект '''ServletContext''', о котором мы поговорим ниже.&lt;br /&gt;
&lt;br /&gt;
Как вы уже, наверное, поняли, объект '''FilterConfig''' позволяет получить доступ к конфигурации фильтра, которая была задана при его объявлении в дескрипторе развертывания ('''web.xml''').&lt;br /&gt;
&lt;br /&gt;
==Ограничение доступа==&lt;br /&gt;
&lt;br /&gt;
Итак, воспользуемся фильтрами для ограничения доступа к ресурсам&lt;br /&gt;
нашего приложения. Прежде всего, запретим пользователю обращаться напрямую к JSP, и, при попытке запросить ресурс из каталога '''/jsps''',&lt;br /&gt;
заставим его перейти на индексную (первую) страницу. Для этого&lt;br /&gt;
напишем простой фильтр '''AccessFilter'''. Метод '''doFilter''' будет выглядеть&lt;br /&gt;
следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
   public void doFilter(ServletRequest aRequest,&lt;br /&gt;
           ServletResponse aResponse, FilterChain filterChain)&lt;br /&gt;
           throws IOException, ServletException {&lt;br /&gt;
              ((HttpServletResponse)aResponse).&lt;br /&gt;
            sendRedirect(((HttpServletRequest)aRequest).getContextPath());&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Благодаря методу '''sendRedirect''', вместо ожидаемого ресурса неавторизованный пользователь увидит '''index.jsp'''. Чтобы фильтр заработал, его необходимо подключить в дескрипторе развертывания. Это делается при помощи следующих строк:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
   &amp;lt;filter&amp;gt;&lt;br /&gt;
       &amp;lt;filter-name&amp;gt;AccessFilterName&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
       &amp;lt;filter-class&amp;gt;AccessFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
   &amp;lt;/filter&amp;gt;&lt;br /&gt;
   &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AccessFilterName&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;url-pattern&amp;gt;/jsps/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
   &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В секции '''filter''' мы объявляем, что имени фильтра '''AccessFilterName'''&lt;br /&gt;
соответствует класс '''AccessFilter''', а в секции '''filter-mapping''' указываем,&lt;br /&gt;
на какие объекты распространяется зона действия фильтра. В данном случае фильтр работает по шаблону, то есть используется для&lt;br /&gt;
всех адресов типа '''/jsps/*''', где вместо звездочки может быть все, что&lt;br /&gt;
угодно.&lt;br /&gt;
&lt;br /&gt;
Теперь давайте создадим класс '''AuthFilter''', который будет ограничивать доступ к некоторым действиям для неавторизованных пользователей. Метод '''doFilter''' будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
   public void doFilter(ServletRequest aRequest,&lt;br /&gt;
          ServletResponse aResponse, FilterChain filterChain)&lt;br /&gt;
          throws IOException, ServletException {&lt;br /&gt;
      HttpSession session = ((HttpServletRequest) aRequest).&lt;br /&gt;
 getSession();&lt;br /&gt;
      String name = (String) session.getAttribute(“auth”);&lt;br /&gt;
      if (name != null) {&lt;br /&gt;
          filterChain.doFilter(aRequest, aResponse);&lt;br /&gt;
      } else {&lt;br /&gt;
          aRequest.setAttribute(“action”, “auth”);&lt;br /&gt;
          RequestDispatcher dispatcher = aRequest.getRequestDispatcher(“/&lt;br /&gt;
 auth”);&lt;br /&gt;
          dispatcher.forward(aRequest, aResponse);&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если в текущей сессии не задан атрибут '''auth''', пользователь будет&lt;br /&gt;
отправлен на страничку авторизации. Добавим в дескриптор развертывания следующие строки:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
   &amp;lt;filter&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthEditFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;filter-class&amp;gt;AuthFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
   &amp;lt;/filter&amp;gt;&lt;br /&gt;
   &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthEditFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;url-pattern&amp;gt;/edit&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
   &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
   &amp;lt;filter&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthAddFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;filter-class&amp;gt;AuthFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
   &amp;lt;/filter&amp;gt;&lt;br /&gt;
   &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthAddFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;url-pattern&amp;gt;/add&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
   &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
   &amp;lt;filter&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthRemFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;filter-class&amp;gt;AuthFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
   &amp;lt;/filter&amp;gt;&lt;br /&gt;
   &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
      &amp;lt;filter-name&amp;gt;AuthRemFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
      &amp;lt;url-pattern&amp;gt;/remove&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
   &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Обратите внимание, что хотя наш фильтр реализован одним-единственным классом, он может быть доступен по нескольким именам (в&lt;br /&gt;
нашем случае: '''AuthEditFilter, AuthAddFilter, AuthRemFilter''') и работать&lt;br /&gt;
для разных URL.&lt;br /&gt;
&lt;br /&gt;
Чтобы закрыть тему развертывания фильтров, рассмотрим пример&lt;br /&gt;
настройки параметров фильтра в дескрипторе:&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
      &amp;lt;init-param&amp;gt;&lt;br /&gt;
          &amp;lt;description&amp;gt;&lt;br /&gt;
              That is description&lt;br /&gt;
          &amp;lt;/description&amp;gt;&lt;br /&gt;
          &amp;lt;param-name&amp;gt;&lt;br /&gt;
              sameParamName&lt;br /&gt;
          &amp;lt;/param-name&amp;gt;&lt;br /&gt;
          &amp;lt;param-value&amp;gt;&lt;br /&gt;
              sameParamValue&lt;br /&gt;
          &amp;lt;/param-value&amp;gt;&lt;br /&gt;
       &amp;lt;/init-param&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Секцию '''init-param''' необходимо создавать отдельно для каждого&lt;br /&gt;
параметра, при этом она должна быть размещена внутри секции '''filter'''.&lt;br /&gt;
Обязательными являются подсекции '''param-name''' и '''param-value''', которые задают название параметра и его значение, соответственно.&lt;br /&gt;
&lt;br /&gt;
==Доступ к общим объектам==&lt;br /&gt;
&lt;br /&gt;
Наше приложение уже вполне работоспособно, однако рано или поздно нам захочется расширить его функциональность, и, возможно, для&lt;br /&gt;
этого потребуется уже не один сервлет, а несколько, причем все они&lt;br /&gt;
будут обращаться к некому общему ресурсу (информации или объектам). Например, вы можете захотеть узнать, сколько пользователей&lt;br /&gt;
в данный момент авторизовано в приложении или получить из двух&lt;br /&gt;
несвязанных сервлетов доступ к информации, хранящейся в одном&lt;br /&gt;
файле.&lt;br /&gt;
&lt;br /&gt;
Подобно сессионным объектам, существует и контекстный объект, который обеспечивает доступ к общим ресурсам из разных мест&lt;br /&gt;
приложения. Использование контекстного объекта очень похоже на&lt;br /&gt;
использование сессионного, и получить его экземпляр в сервлете можно следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=java&amp;gt;&lt;br /&gt;
 ServletContext sc = this.getServletContext();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот объект обладает следующими методами:&lt;br /&gt;
&lt;br /&gt;
* '''getAttribute(String)''' – получение общего объекта по ключу;&lt;br /&gt;
* '''getAttributeNames()''' – получение списка ключей общих объектов;&lt;br /&gt;
* '''setAttribute(String, Object)''' – добавление нового объекта и соответствующего ему ключа;&lt;br /&gt;
* '''removeAttribute(String)''' – удаление объекта, соответствующего ключу, из списка общедоступных объектов;&lt;br /&gt;
&lt;br /&gt;
Несмотря на то, что в этой статье контекстному объекту уделено&lt;br /&gt;
немного внимания, он является одним из мощнейших инструментов&lt;br /&gt;
для обеспечения работы web-приложения.&lt;br /&gt;
&lt;br /&gt;
==Вместо заключения==&lt;br /&gt;
&lt;br /&gt;
Сегодня мы поговорили о сессионных и контекстных объектах, узнали&lt;br /&gt;
как создавать и использовать фильтры, рассмотрели простейший пример авторизации пользователя (конечно, надо сделать оговорку, что&lt;br /&gt;
было представлено весьма небезопасное и не промышленное решение,&lt;br /&gt;
хотя для простого офисного приложения его может быть и достаточно).&lt;br /&gt;
Наконец, мы модифицировали наше web-приложение «Телефонная&lt;br /&gt;
книга», применяя практически все изученные возможности.&lt;br /&gt;
&lt;br /&gt;
В следующий раз мы рассмотрим паттерн ''MVC'' и его вариацию для&lt;br /&gt;
создания web-приложений: ''Model2''. '''LXF'''&lt;/div&gt;</summary>
		<author><name>Moradan</name></author>	</entry>

	</feed>