0

I've recently tried to upgrade a system to timeout user sessions through the web.xml file, set to 10 minutes, with a Filter redirecting to my login page as well as a PhaseListener to keep track of user activity.

My Login bean, on instantiation, does the following:

private User user; //this already has getters/setters

public LoginBean() {
    log.info("Instantiating Login Bean...");
    if(!hasSessionData("user")) {
        user = new User();
        Dealer dealer = new Dealer();
        user.setDealer(dealer);
        setSessionData("user",user);
    }       
}

This opens the login form and uses User to contain login details for submission. However, if I sit on the login screen for more than 10 minutes (session expire) and I attempt to login, I get an error.

Aug 01, 2013 10:32:20 AM com.sun.faces.lifecycle.ProcessValidationsPhase execute
WARNING: /Login30FrmView.xhtml @108,92 value="#{loginBean.user.dealerId}": Target Unreachable, 'user' returned null
javax.el.PropertyNotFoundException: /Login30FrmView.xhtml @108,92 value="#{loginBean.user.dealerId}": Target Unreachable, 'user' returned null
    at com.sun.facelets.el.TagValueExpression.getType(TagValueExpression.java:62)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:92)
    at javax.faces.component.UIInput.getConvertedValue(UIInput.java:942)
    at javax.faces.component.UIInput.validate(UIInput.java:868)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1072)
    at javax.faces.component.UIInput.processValidators(UIInput.java:672)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)
    at javax.faces.component.UIForm.processValidators(UIForm.java:234)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)
    at org.ajax4jsf.component.AjaxViewRoot$3.invokeContextCallback(AjaxViewRoot.java:447)
    at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:240)
    at org.ajax4jsf.component.AjaxViewRoot.processValidators(AjaxViewRoot.java:463)
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
    at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
    at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
    at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

Aug 01, 2013 10:32:20 AM com.sun.faces.lifecycle.Phase doPhase SEVERE: JSF1054: (Phase ID: PROCESS_VALIDATIONS 3, View ID: /Login30FrmView.xhtml) Exception thrown during phase execution: javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@7d137b]

I am wondering why user is returning null when the LoginBean is still initialized according to log. On session expire, user in session expires as well, so if(!hasSessionData("user")) should return true and initialize user again. But if user has to be re-initialized on page load and it times out on page...how can that be done? My Filter redirects to login whenever a session is destroyed like so:

if (isSessionInvalid(httpServletRequest)) {
    String timeoutUrl = httpServletRequest.getContextPath() + "/" + getTimeoutPage();
          httpServletResponse.sendRedirect(timeoutUrl);
          System.out.println("Redirecting to login page");
          return;
          }
    }

But somehow I need this to trigger when the form is submitted and session expired, which it doesn't seem to do as it is...I don't have much experience with this so I want to know if this is possible? How can I get user initialized again for form submit once session expires?

(Note that refreshing the page makes everything fine again, but I'm going to get a lot of complaints from end-users if I let scary error messages even appear.)

EDIT: My login submit uses a <h:commandButton> and points to a listener in my LoginBean. Is there any way to catch if this is submitted so I can revert to login page when the above occurs? This may be a possible alternate solution. I just really want that error to go away, even if it jumps the user back to login without explanation.

Mark M
  • 1,550
  • 10
  • 21
  • Have you added `@SessionScoped` in the User Class? – EProgrammerNotFound Aug 01 '13 at 02:19
  • Are you sure that's all the stacktrace? – Luiggi Mendoza Aug 01 '13 at 02:24
  • Related (since you didn't show all your managed bean configuration): http://stackoverflow.com/q/8728487/1065197 – Luiggi Mendoza Aug 01 '13 at 02:25
  • @MatheusFreitas I'm using JSF 1.1 so I use faces-config.xml to set it in session scope. Like I said, login works completely fine until I idle at the login page long enough for session timeout. – Mark M Aug 01 '13 at 02:37
  • @LuiggiMendoza I've added the full stacktrace. Also saw all the various related errors, I think mine is unique in that login already works; just not when you stay on the login page long enough to time out. Refreshing the page allows you to login normally. – Mark M Aug 01 '13 at 02:38

1 Answers1

0

Answering my own question since I found a solution. I simply had to add this line to my Login Form.

<meta http-equiv="refresh" content="#{session.maxInactiveInterval}"/>

This refreshes the form before timeout to preserve the session, thus ensuring that there is always a user in session since refreshing instantiates the bean and loads the page again.

Mark M
  • 1,550
  • 10
  • 21