Сессии в приложении struts2

Я создал веб-приложение, в котором мне нужно поддерживать сеанс если пользовательский сеанс есть, а затем и только тогда он позволит пользователю увидеть jsp.

Я работал с сервлетами jsp раньше, но я новичок в struts2.

Здесь я задаю имя пользователя в своем классе действий:

Пересмотренный код

private HttpSession session;

public void setSession(HttpSession session) {
    // TODO Auto-generated method stub0
    this.session = session;
}

public HttpSession getSession() {
    return session;
}

public String getLoginStatus(){     
    session = request.getSession();
    session.setAttribute("userName", loginBean.getUsername());
    return SUCCESS;
}

Теперь, когда я перенаправляется на следующую страницу после действия, он показывает значение сеанса один раз. После этого на каждой странице я нахожу нулевые значения в сеансе.

<%
    String userName = (String)session.getAttribute("userName");             
    System.out.println(userName);                        

    if(userName == null || userName.equals("") ){
        response.sendRedirect("login.jsp");
    }

%>

Я где-то читал, что объем сеанса действия класса ограничен одной страницей - как я могу решить эту проблему?

Любой пример будет очень полезен для меня.

Ответ 1

Есть несколько проблем с кодом, который у вас есть.

  • Вы должны использовать Interceptor для обеспечения того, чтобы пользователь вошел в систему, вместо того, чтобы пытаться применить его в JSP. JSP должен быть предназначен только для представления, а не для управления потоком.
  • Вам следует избегать сценариев (блоков кода) в JSP. Это было устарело очень давно и широко считается очень плохой практикой в ​​приложении MVC.
  • Вы можете получить доступ к значениям сеанса в своем JSP напрямую. Вам не нужно реализовывать интерфейс SessionAware в вашем действии, если вам не нужен доступ к сеансу внутри самого действия.
  • Вы должны перенаправить пользователя на действие входа, а не непосредственно на страницу JSP, иначе вы обойдете инфраструктуру Struts2 и проиграете преимущества использования фреймворка.

Пример входа

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

Требуется вход

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

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

public interface LoginRequired {}

Перехватчик

Перехватчик будет обрабатывать принуждение пользователя к вводу для любого запрошенного действия, которое реализует интерфейс LoginRequired.

public class LoginInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(final ActionInvocation invocation) throws Exception {
        Map<String, Object> session = ActionContext.getContext().getSession();

        // sb: feel free to change this to some other type of an object which
        // represents that the user is logged in. for this example, I am using
        // an integer which would probably represent a primary key that I would
        // look the user up by with Hibernate or some other mechanism.
        Integer userId = (Integer) session.get("userId");

        // sb: if the user is already signed-in, then let the request through.
        if (userId != null) {
            return invocation.invoke();
        }

        Object action = invocation.getAction();

        // sb: if the action doesn't require sign-in, then let it through.
        if (!(action instanceof LoginRequired)) {
            return invocation.invoke();
        }

        // sb: if this request does require login and the current action is
        // not the login action, then redirect the user
        if (!(action instanceof LoginAction)) {
            return "loginRedirect";
        }

        // sb: they either requested the login page or are submitting their
        // login now, let it through
        return invocation.invoke();
    }
}

Вам также понадобится LoginAction, который отображает и обрабатывает страницу входа и LogoutAction, которая отменяет или очищает сеанс.

Конфигурация

Вам нужно будет добавить перехватчик в свой стек, а также создать глобальное сопоставление результатов для "loginRedirect".

<interceptors>
    <interceptor name="login" class="your.package.LoginInterceptor"/>

    <!-- sb: you need to configure all of your interceptors here. i'm only
         listing the one we created for this example. -->
    <interceptor-stack name="yourStack">
        ...
        <interceptor-ref name="login"/>
        ...
    </interceptor-stack>
</interceptors>

<global-results>
    <!-- sb: make this the path to your login action.
         this could also be a redirectAction type. -->
    <result name="loginRedirect" type="redirect">/login</url>
</global-results>

Ответ 2

Чтобы поддерживать сеанс, используйте SessionAware интерфейс в своем классе действий и реализуйте int public void setSession (Карта m), он примет атрибут как пару ключевых значений в карте к которому можно получить доступ из любого места, где можно просто купить ключ.

например Класс действия

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;

public class LogingEx extends ActionSupport implements SessionAware{
    private static final long serialVersionUID = 1L;

    private String stuname,stuage,country;
    private int stumarks;
    Map m;

    public String getStuname() {
        return stuname;
    }
    public void setStuname(String stuname) {
        this.stuname = stuname;
    }

    public String getStuage() {
        return stuage;
    }
    public void setStuage(String stuage) {
        this.stuage = stuage;
    }

    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }

    public int getStumarks() {
        return stumarks;
    }
    public void setStumarks(int stumarks) {
        this.stumarks = stumarks;
    }

    public void setSession(Map m)
    {
        this.m=m;
    }

    public String execute()
    {
        m.put("a",stuname);
        m.put("b", stuage);
        m.put("c",stumarks);
        m.put("d",country);

        return SUCCESS;
    }

}

ИСТОЧНИК: http://www.java4s.com/struts-tutorials/example-on-struts-2-sessionaware-interface/

Ответ 3

Я не нахожу причины использовать этот тип Map для авторизации пользователя. Если ваше требование только проверяет пользователя на сеанс, я бы рекомендовал использовать Filter, чем какую-либо карту в каком-то классе, проблема с этим видом карты заключается в удалении объектов сеанса, когда сеанс недействителен, конечно, вы можете использовать HttpSessionListener, чтобы он работал, но я думаю, что лучше всего проверить с помощью Filter, чем Map.

Помимо этого вы можете взглянуть на многие рамки безопасности (например, Apache Shiro), чтобы сделать вашу задачу более простой и надежной.

Ответ 4

Разве ваш класс Action уже реализовал интерфейс SessionAware?

EDIT:

Попробуйте это (это решение стиля struts2):

public class anAction implements SessionAware{
    private Map<String, Object> session;
    public Map<String, Object> getSession() {
         return session;
    }
    public void setSession(Map<String, Object> session) {
         this.session = session;
    }
    public String getLoginStatus(){
         session.put("userName", "test");  //Hard code here for testing.
         return SUCCESS;
    }
}

Затем используйте свой код jsp, чтобы получить имя пользователя на странице. Я тестировал этот подход на своей машине, и он работает.

EDIT2: BTW, такая проверка входа может быть выполнена легко и элегантно с помощью "Interceptor", предоставляемого Struts2 Framework.

Ответ 5

Выполнение SessionAware не требуется.

public class LoginAction extends Actionsupport
{
  private Map<String, Object> session;
  //Getter and Setter method
   public String execute() throws Exception {
      session=ActionContext.getContext().getSession();
      session.put("userName", "test");
     return super.execute();
   }
}