CookieCounter.printToBrowser(resp, req);
В классе CookieCounter производится модификация файла cookie, хранимого на компьютере клиента.
/* пример # 4 : создание cookie и чтение количества вызовов сервлета из cookie : CookieCounter.java */
package chapt16;
import java.io.IOException;
import java.io.Writer;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieCounter {
/* константа, которая будет использована для установки максимального
времени жизни cookie (здесь указано 30 дней) */
public static final int MAX_AGE_COOKIE = 3600 * 24 * 30;
public static void printToBrowser(
HttpServletResponse response, HttpServletRequest request) {
try {
Writer out = response.getWriter();
out.write("My Cookie counter: ");
/* устанавливает счетчик количества вызовов сервлета пользователем */
out.write(String.valueOf(prepareCookieCounter(
request,response)));
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Failed: " + e);
}
}
// обновляет в сookie счетчик обращений пользователя к сервлету
private static int prepareCookieCounter(
HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
Cookie counterCookie;
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if ("counter".equals(cookies[i].getName())) {
String counterStr = cookies[i].getValue();
int counterValue;
try {
counterValue = Integer.parseInt(counterStr);
} catch (NumberFormatException e) {
counterValue = 0;
}
counterValue++;
counterCookie = new Cookie("counter",
String.valueOf(counterValue));
counterCookie.setMaxAge(MAX_AGE_COOKIE);
response.addCookie(counterCookie);
return counterValue;
}//end if
}//end for
} //end if
counterCookie = new Cookie("counter", "1");
counterCookie.setMaxAge(MAX_AGE_COOKIE);
response.addCookie(counterCookie);
return 1;
}
}
В результате в файле cookie будет содержаться следующая информация:
Counter
localhost/FirstProject/
*
В браузер будет выведено следующее сообщение:
My session counter: 1
Обработка событий
Существует несколько интерфейсов, которые позволяют следить за событиями, связанными с сеансом, контекстом и запросом сервлета, генерируемыми во время жизненного цикла Web-приложения:
- javax.servlet.ServletContextListener – обрабатывает события создания/удаления контекста сервлета;
- javax.servlet.http.HttpSessionListener – обрабатывает события создания/удаления HTTP-сессии;
- javax.servlet.ServletContextAttributeListener – обрабатывает события создания/удаления/модификации атрибутов контекста сервлета;
- javax.servlet.http.HttpSessionAttributeListener – обрабатывает события создания/удаления/модификации атрибутов HTTP-сессии;
- javax.servlet.http.HttpSessionBindingListener – обрабатывает события привязывания/разъединения объекта с атрибутом HTTP-сессии;
- javax.servlet.http.HttpSessionActivationListener – обрабатывает события связанные с активацией/дезактивацией HTTP-сессии;
- javax.servlet.ServletRequestListener – обрабатывает события создания/удаления запроса;
- javax.servlet.ServletRequestAttributeListener – обрабатывает события создания/удаления/модификации атрибутов запроса сервлета.
Интерфейсы и их методы |
ServletContextListener contextDestroyed(ServletContextEvent e) contextInitialized(ServletContextEvent e) |
HttpSessionListener sessionCreated(HttpSessionEvent e) sessionDestroyed(HttpSessionEvent e) |
ServletContextAttributeListener attributeAdded(ServletContextAttributeEvent e) attributeRemoved(ServletContextAttributeEvent e) attributeReplaced(ServletContextAttributeEvent e) |
HttpSessionAttributeListener attributeAdded(HttpSessionBindingEvent e) attributeRemoved(HttpSessionBindingEvent e) attributeReplaced(HttpSessionBindingEvent e) |
HttpSessionBindingListener valueBound(HttpSessionBindingEvent e) valueUnbound(HttpSessionBindingEvent e) |
HttpSessionActivationListener sessionWillPassivate(HttpSessionEvent e) sessionDidActivate(HttpSessionEvent e) |
ServletRequestListener requestDestroyed(ServletRequestEvent e) requestInitialized(ServletRequestEvent e) |
ServletRequestAttributeListener attributeAdded(ServletRequestAttributeEvent e) attributeRemoved(ServletRequestAttributeEvent e) attributeReplaced(ServletRequestAttributeEvent e) |
Регистрация блока прослушивания производится в дескрипторном файле приложения.
Демонстрация обработки событий изменения состояния атрибутов сессии будет рассмотрена на примере №1 данной главы. Обрабатываться будут события добавления атрибута URL, а также добавления и изменения атрибута счетчика counter. Для этого необходимо создать класс, реализующий интерфейс HttpSessionAttributeListener и реализовать необходимые для выполнения поставленной задачи методы.
/* пример # 5 : обработка событий добавления и изменения атрибута сессии : MyAttributeListener.java */
package chapt21;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
public class MyAttributeListener
implements HttpSessionAttributeListener {
private String counterAttr = "counter";
public void attributeAdded(HttpSessionBindingEvent ev) {
String currentAttributeName = ev.getName();
String urlAttr = "URL";
if (currentAttributeName.equals(counterAttr)) {
Integer currentValueInt = (Integer) ev.getValue();
System.out.println("в Session добавлен счетчик="
+ currentValueInt);
} else if (currentAttributeName.equals(urlAttr)) {
StringBuffer currentValueStr = (StringBuffer)ev.getValue();
System.out.println("в Session добавлен URL="
+ currentValueStr);
} else System.out.println("добавлен новый атрибут");
}
public void attributeRemoved(HttpSessionBindingEvent ev) {
}
public void attributeReplaced(HttpSessionBindingEvent ev) {
String currentAttributeName = ev.getName();
// в случае изменений, произведенных со счетчиком,
// выводит соответствующее сообщение
if (currentAttributeName.equals(counterAttr)) {
Integer currentValueInt = (Integer) ev.getValue();
System.out.println("В Session заменен cчетчик="
+ currentValueInt);
}
}
}
Чтобы события обрабатывались, необходимо включить упоминание об обработчике событий в элемент <web-app> дескрипторного файла web.xml.
<listener>
<listener-class>chapt21.MyAttributeListener </listener-class>
</listener>
Тогда в результате запуска сервлета SessionServlet и нескольких обращений к нему в консоль будет выведено:
в Session добавлен URL= http://localhost:8080/FirstProject/SessionServlet
в Session добавлен счетчик=1
в Session заменен cчетчик=1
в Session заменен cчетчик=2
в Session заменен cчетчик=3
Интерфейс ServletRequestListener добавлен в Servlet API начиная
с версии 2.4. С его помощью можно отследить события создания запроса при обращении к сервлету и его уничтожении.
/* пример # 6 : обработка событий создания и уничтожения запроса к сервлету : MyRequestListener.java */
package chapt21;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
public class MyRequestListener
implements ServletRequestListener {
// счетчик числа обращений к сервлету
private static int reqCount;
public void requestInitialized(ServletRequestEvent e) {
//будет использован для доступа к log-файлу
ServletContext context = e.getServletContext();
//будет использован для получения информации о запросе
ServletRequest req = e.getServletRequest();
synchronized (context) {
String name = "";
name = ((HttpServletRequest) req).getRequestURI();
// сохранение значения счетчика в log-файл
context.log("Request for " + name
+ "; Count=" + ++reqCount);
}
}
public void requestDestroyed(ServletRequestEvent e) {
// вызывается при уничтожении запроса
System.out.println("Request уничтожен");
}
}
В результате запуска сервлета SessionServlet, в log-файл, расположенный в каталоге /logs контейнера сервлетов, будет выведено: