Witam.
Na początku zaznaczę, że programowaniem w Javie zajmuję się od kilku lat, ale JEE uczę się dopiero od tygodnia.
Mój problem dotyczy zarządzaniem sesją w JSF. Napisałem prostą aplikację, która po zalogowaniu usera, ustawia odpowiedni obiekt UserSessionBean jako atrybut sesji, tak aby mieć potem wygodny do niego dostęp. Sam proces logowania odbywa się poprzez prosty formularz (używam kontrolek PrimeFaces, stąd <p:...>):
<h:form>
<p:panel header="Logowanie">
<h:panelGrid columns="2">
<h:outputText value="Użytkownik: " />
<p:inputText value="#{userForm.userName}"/>
<h:outputText value="Hasło: " />
<p:password value="#{userForm.password}" feedback="false" minLength="3"/>
<p:commandButton value="Zaloguj" action="#{userForm.login}" update="growl" ajax="false"/>
</h:panelGrid>
</p:panel>
</h:form>
Klasa odpowiedzialna za logowanie (najważniejszy fragment):
@ManagedBean(name = "userForm")
@SessionScoped
public class UserForm implements HttpSessionListener{
private PostgreManager pm;
@ManagedProperty(value = "#{userSession}")
private UserSessionBean userSession;
private String userName;
private String password;
public String login() {
try {
try {
pm = PostgreManager.getInstance();
} catch (ClassNotFoundException ex) {
Logger.getLogger(UserForm.class.getName()).log(Level.SEVERE, null, ex);
}
UserBean user = null;
try {
user = pm.validateLogin(getUserName(), getPassword(), false);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(UserForm.class.getName()).log(Level.SEVERE, null, ex);
}
if (user != null) {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
userSession = (UserSessionBean) session.getAttribute(UserSessionFilter.MANAGED_BEAN_NAME);
userSession.setUser(user);
session.setAttribute(UserSessionFilter.MANAGED_BEAN_NAME, userSession);
return "valid";
} else {
// Do your error handling thing.
setErrorMessage("Podano zły login lub hasło.");
}
} catch (SQLException e) {
// Do your exception handling thing.
setErrorMessage("Błąd przy łączeniu z bazą.", e);
}
return null;
}
public String logout() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
userSession = (UserSessionBean) session.getAttribute(UserSessionFilter.MANAGED_BEAN_NAME);
userSession.setUser(null);
session.setAttribute(UserSessionFilter.MANAGED_BEAN_NAME, userSession);
return "logout";
}
}
W faces-config.xml mam następującą regułę, dotyczącą nawigacji:
<navigation-rule>
<from-view-id>/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>valid</from-outcome>
<to-view-id>/view.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
Mój problem polega na tym, że podczas logowania, przy przechodzeniu z /login.xhtml do /view.xhtml sesja zostaje zamknięta (sprawdzałem to ustawiając odpowiedni HttpSessionListener ) a w jej miejsce zostaje wstawiona nowa sesja, przez co nie mam już dostępu do atrybutu UserSessionBean. Dodam, że w web.xml timeout jest standardowy = 30 minut. Co może być tego powodem i jak sprawić, aby sesja nie została usunięta.
Dodam jeszcze stack trace, jaki otrzymałem po umyślnym wyrzuceniu wyjątku w metodzie sessionDestroyed() obiektu nasłuchującego:
2011-07-30 15:18:13 UserForm sessionDestroyed
FINE: Niszczenie sesji
java.lang.Exception: sesja zlikwidowana
at UserForm.sessionDestroyed(UserForm.java:152)
at org.apache.catalina.session.StandardSession.expire(StandardSession.java:807)
at org.apache.catalina.session.StandardSession.expire(StandardSession.java:769)
at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:686)
at org.apache.catalina.session.StandardManager.processExpires(StandardManager.java:996)
at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:5717)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1790)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1779)
at java.lang.Thread.run(Thread.java:662)
Wygląda na to, że moja sesja wygasła z nieznanych mi przyczyn.