Struts2 - сессия

Объект сессии ( session ) в WEB-приложении имеет немаловажное значение. При использовании Struts2 можно использовать сессию интерфейса ServletRequest, который расширяется интерфейсом HttpServletRequest. Метод getSession (boolean create) данного интерфейса возвращает объект типа HttpSession текущего сеанса клиента. Если параметр create равен true и объект HttpSession не существует, то создается новый объект HttpSession.

Интерфейс SessionAware

В книге "Struts2 in Action" указывается, что несмотря на возможность использования HttpSession необходимо все же использовать родной объект сессии. Для этого необходимо создать действие, которое наследует интерфейс SessionAware. Интерфейс SessionAware содержит метод setSession, который открывает нам доступ к сессии фреймворка. Параметром метода setSession является объект типа Map <String, Object>. Таким образом, определив в действии объект типа Map <String, Object>, мы можем связать его с сессией фреймворка. После этого, сессию можно использовать для обмена объектами между различными действиями.

Необходимо отметить, что перехватчики ( Interceptor ) наследуют интерфейс SessionAware, получая доступ к объекту сессии. Такая структура фреймворка позволяет использовать перехватчики для проверки авторизации (наличия пользователя в сессии) при попытке "незванного гостя" попасть в закрытые области (страницы) WEB-приложения.
Рассмотрим вопрос использования сессии на примере авторизации пользователя. Суть данного примера заключается в проверке наличия пользователя с определенным аккаунтом в нашем хранилище ( базе данных ). Если пользователь присутствует, то объект User добавляется к сессии и вызывается действие главной формы. В главной форме можно использовать сессию для получения доступа к объекту и отображения параметров его аккаунта.

Вызов Action-класса авторизации Authentication выполняется на странице Login.jsp.

Наследование ActionSupport

В листинге Authentication.java приведен исходный код действия авторизации пользователя. На что следует обратить внимание?
  1. import org.apache.struts2.interceptor.SessionAware - наследование интерцептором;

    • сессия может быть использована в интерцепторах; В примере раздела о перехватчиках приводится код получения сессии для проверки авторизации пользователя, чтобы предотвратить недопустимый переход в закрытые области приложения;
  2. extends ActionSupport - наследование свойств и методов класса, который вызывает execute () и validate ();

    • в методе execute () выполняем авторизацию пользователя;
    • в методе validate () реализовываем логику проверки данных;
  3. implements SessionAware - включение свойств класса;

    • наследование интерфейса SessionAware определяет необходимость включения в класс процедуры setSession, которая вызывается фреймворком и, в коде которой, мы определяем переменную сессии session;

Действие авторизации пользователя

Листинг действия Authentication.java
      
  package examples.registration;
 
  import java.util.Map;
  import org.apache.struts2.interceptor.SessionAware;
  import com.opensymphony.xwork2.Action;
  import com.opensymphony.xwork2.ActionSupport;
 
  public class Authentication extends ActionSupport implements SessionAware {
 
   private String login;
   private String password;
   private Map<String, Object> session;
 
   public String execute() throws Exception {
    Store store = new Store();
    if (( store != null ) && ( store.userExists ( getLogin (), getPassword ())))
    {
     User user = store.getUser ( getLogin (), getPassword ());
     session.put ( "user", user );
     return Action.SUCCESS;
    } else
     return Action.INPUT;
   }
 
   public void setSession ( Map session ) {
    this.session = session;
   }
 
   public String getLogin {
    return login;
   }
 
   public void setLogin (String login) {
    this.login = login;
   }
 
   public String getPassword {
    return password;
   }
 
   public void setPassword (String password) {
    this.password = password;
   }
 
   private boolean isEmptyString ( String value ) {
    return value == null || "".equals ( value.trim ( ) );
   }
 
   public void validate ( ) {
    if ( isEmptyString ( login ))
     addFieldError ( "login", "Не указан логин" );
    if ( isEmptyString ( password ))
     addFieldError ( "password", "Не указан пароль" );
   }
  }

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

Фреймворк вызывает метод setSession, в котором мы определяем нашу переменную session. Получив доступ к сессии, мы в методе execute () извлекаем объект User из хранилища и размещаем его в сессии. Структура объекта User приводится в следующем листинге.

Объект пользователя User.java
    
  package examples.registration;
 
  public class User
  {
 
   private String name;
   private String login;
   private String password;
 
   public String getName {
    return name;
   }
 
   public void setName (String name) {
    this.name = name;
   }
 
   public String getLogin {
    return login;
   }
 
   public void setLogin (String login) {
    this.login = login;
   }
 
   public String getPassword {
    return password;
   }
 
   public void setPassword (String password) {
    this.password = password;
   }
  }

Подключение действия авторизации к приложению

Подключение действия к WEB-приложению осуществляется в файле конфигурации struts.xml.

Листинг файла конфигурации struts.xml
     
  <package name="public" namespace="/Public" extends="struts-default">
 
   <action name="Login">
    <result>/Login.jsp</result>
   </action>
 
   <action name="Authentication" class="examples.registration.Authentication">
    <result name="success" type="redirect">/Private/MainPage.action</result>
    <result name="input">/Login.jsp</result>
    </action>
 
  </package>

В данном файле конфигурации мы определили, что действие Authentication располагается в открытой области (namespace) Public. Для выполнения данного действия необходимо вызвать класс examples.registration.Authentication.class. Если результат выполнения действия будет success, то необходимо выполнить действие MainPage.action закрытой области Private. Если действие Authentication не авторизует пользователя, т.е. результат выполнения будет input, то остаемся на странице Login.jsp.

Вызов действия авторизации

Представим страницу Login.jsp, в которой оператор будет вводить данные и вызывать действие Authentication.

Листинг JSP-страницы Login.jsp
 
  <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
  <%@ taglib prefix="s" uri="/struts-tags" %>
 
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html>
   <head>
    <title>Авторизация пользователя</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   </head>
   <body>
    <h1>Авторизация пользователя</h1>
    <s:form action="Authentication" method="post">
     <s:textfield label="Логин" name="login" required="true" ></s:textfield>
     <s:password label="Пароль" name="password" required="true" />
     <s:submit value="Подключиться"></s:submit>
    </s:form>
   </body>
  </html>
 

В представленном листинге страницы Login.jsp следует обратить внимание на способы закрытия тегов. Теги Struts2 можно закрывать с объявлением (</s:textfield>) и без объявления (/>). Параметр required определяет установку символа * для представления поля как обязательного к заполнению.

Использование объектов сессии на странице JSP

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

Фрагмент листинга страницы JSP
  
  <%@ page import="examples.registration.User" %>
  <% User user = (User) session.getAttribute ("user"); %>
  Добро пожаловать, <h3><%= user.getName() %></h3>
 


Rambler's Top100 Рейтинг@Mail.ru