Sesje w aplikacji struts2

Stworzyłem aplikację internetową, w której muszę utrzymać sesję jeśli istnieje sesja użytkownika, a wtedy i tylko wtedy pozwoli użytkownikowi zobaczyć jsp.

Pracowałem już z serwletami jsp, ale jestem nowy w struts2.

Oto jestem Ustawianie nazwy użytkownika w mojej klasie działania :

Poprawiony Kod

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;
}

Teraz, Kiedy jestem przekierowany do następnej strony po operacji, wyświetla wartość sesji raz. Potem, na każdej stronie znajduję wartości null w sesji.

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

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

%>

Czytałem gdzieś, że zakres sesji klasy action jest ograniczony do jednej strony - Jak mogę rozwiązać ten problem?

Każdy przykład będzie dla mnie bardzo pomocny.
Author: Hannele, 2011-04-01

6 answers

Jest kilka problemów z kodem, który aktualnie masz.

  • powinieneś użyć Interceptora, aby wymusić, że użytkownik jest zalogowany, zamiast próbować wymusić to w JSP. JSP powinien być tylko do prezentacji, a nie do kontroli przepływu.
  • należy unikać skryptów (bloków kodu) w JSP. To było przestarzałe naprawdę dawno temu i jest powszechnie uważane za bardzo słabą praktykę w aplikacji MVC.
  • możesz uzyskać dostęp do wartości sesji w JSP bezpośrednio. Nie musisz implementować interfejsu SessionAware w swojej akcji, chyba że potrzebujesz dostępu do sesji wewnątrz samej akcji.
  • powinieneś przekierować użytkownika do akcji logowania, a nie bezpośrednio do strony JSP, w przeciwnym razie omijasz Framework Struts2 i tracisz korzyści z używania frameworku.

Przykład Logowania

Poniżej znajduje się przykładowy kod do tworzenia podstawowego systemu logowania przy użyciu frameworka Struts2.

Login Wymagane

Ta część jest opcjonalna, ale ogólnie rzecz biorąc, nie wszystkie strony w aplikacji internetowej wymagają zalogowania użytkownika. Dlatego stwórzmy interfejs o nazwie LoginRequired. Każda akcja implementująca ten interfejs znacznika przekieruje na stronę logowania, jeśli użytkownik nie jest jeszcze zalogowany.

Uwaga: Możesz zamiast tego użyć adnotacji, jeśli wolisz, ale w tym przykładzie użyję interfejsu.

public interface LoginRequired {}

Przechwytujący

Przechwytujący poradzi sobie zmuszanie użytkownika do zalogowania się dla żądanej akcji implementującej interfejs 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();
    }
}

Będziesz również potrzebował LoginAction, która wyświetla i przetwarza stronę logowania oraz LogoutAction, która unieważnia lub czyści sesję.

Konfiguracja

Będziesz musiał dodać interceptor do stosu, a także utworzyć globalne mapowanie wyników dla "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>
 36
Author: Steven Benitez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-01 18:46:32

Aby utrzymać sesję Użyj interfejsu SessionAware w swojej klasie akcji i zaimplementuj int public void setSession (Map m) {[3] } atrybut zostanie użyty jako para wartości klucza w map który może być dostęp z dowolnego miejsca, gdzie wystarczy kupić klucz.

Na przykład Klasa akcji

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;
    }

}

Źródło: http://www.java4s.com/struts-tutorials/example-on-struts-2-sessionaware-interface/

 6
Author: Arvind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-21 06:27:06

Nie znajduję powodu, aby używać tego rodzaju Map do autoryzacji użytkownika. Jeśli twoim wymogiem jest tylko Walidacja użytkownika względem sesji, to polecam użyć Filter niż jakiejś mapy w jakiejś klasie, problem z tego rodzaju mapą polega na usunięciu obiektów sesji po unieważnieniu sesji, oczywiście możesz użyć HttpSessionListener, aby to działało, ale myślę, że najlepiej jest zweryfikować przez Filter niż Map.

Oprócz tego można przyjrzeć się wielu frameworkom bezpieczeństwa (jak Apache Shiro ), aby Uprość swoje zadanie i zwiększ jego wytrzymałość.

 2
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-01 06:06:31

Czy twoja klasa działania zaimplementowała już Interfejs SessionAware?

EDIT:

Try this(It ' s a struts2 style solution):

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;
    }
}

Następnie użyj kodu jsp, aby uzyskać nazwę użytkownika na stronie. Przetestowałem to podejście na mojej maszynie i działa.

EDIT2: BTW, takie sprawdzenie logowania można zrobić łatwo i elegancko z "Interceptor" dostarczonym przez Struts2 Framework.

 2
Author: RollingBoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-01 06:50:34

SessionAware implementacja nie jest wymagana.

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();
   }
} 
 0
Author: hari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-17 05:34:04

Następujący artykuł journaldev ma więcej szczegółów w tej samej linijce odpowiedzi Stevena powyżej http://www.journaldev.com/2210/struts-2-interceptor-tutorial-with-custom-authentication-interceptor-example

 0
Author: rajnish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-01 19:04:15