3 Replies Latest reply on Aug 11, 2006 3:45 AM by Basel Al-Mustafa

    Graceful logout and friendly login ? How to?

    Basel Al-Mustafa Newbie

      In short, how can I keep track of the GET request parameters and the URL when users login and logout?

      For instance, blogEntry.jsf depends on a request parameter called id and a page action entryAction.setEntry. Moreover, login and logout are performed using the two page actions loginAction.login and loginAction.logout.

      Scenario 1 ? login:
      It is common for the user to login after viewing blogEntry.jsf?id=35. Now, the user would expect blogEntry.jsf?id=35 to be displayed again after the login. For this to work, loginAction.login has to know the view name from which the user clicked on login and any request parameters that were present. However, not knowing this information forces loginAction.login to return ?/home.jsf? so that the user is redirected to the home page.

      Scenario 2 - logout:
      The user is already logged in and is currently viewing blogEntry.jsf?id=35. The user clicks on logout and as a result loginAction.logout returns null so that the current page is redisplayed. At this point the user is redirected to blogEntry.jsf instead of blogEntry.jsf?id=35. As a result, the page action entryAction.setEntry returns a new Entry object that has no properties set.

      I tried to access the HttpServletRequest in the second scenario but calling getNames() method on it returned only one parameter which is the conversationId.

      I would appreciate any ideas or suggestions that would help in avoiding these two scenarios.

        • 1. Re: Graceful logout and friendly login ? How to?
          Stan Silvert Master

           

          "Basel" wrote:


          Scenario 1 ? login:
          It is common for the user to login after viewing blogEntry.jsf?id=35. Now, the user would expect blogEntry.jsf?id=35 to be displayed again after the login. For this to work, loginAction.login has to know the view name from which the user clicked on login and any request parameters that were present. However, not knowing this information forces loginAction.login to return ?/home.jsf? so that the user is redirected to the home page.


          You can easily know the view and the request params using the standard JSF EL variables "view" and "facesContext":

          @In
          private UIViewRoot view
          
          @In(value="#{facesContext.externalContext.requestParameterMap}")
          private Map reqParams;


          With Seam's new action params feature you also have the option to forego the instance variables and pass these values directly to your action:

          From JSP or Facelets:
          <s:commandLink action="#{loginAction.login(view, facesContext.externalContext.requestParameterMap)}" />


          In Seam component:
          public String login(UIViewRoot view, Map reqParams) {
           // blah blah
          }


          The action params feature is now in the nightly build.

          "Basel" wrote:

          Scenario 2 - logout:
          The user is already logged in and is currently viewing blogEntry.jsf?id=35. The user clicks on logout and as a result loginAction.logout returns null so that the current page is redisplayed. At this point the user is redirected to blogEntry.jsf instead of blogEntry.jsf?id=35. As a result, the page action entryAction.setEntry returns a new Entry object that has no properties set.

          I tried to access the HttpServletRequest in the second scenario but calling getNames() method on it returned only one parameter which is the conversationId.

          I would appreciate any ideas or suggestions that would help in avoiding these two scenarios.


          I don't understand. Why do you have to return null from your action? Usually, a logout action sends you to a standard "You've logged out" page.

          Also, you should avoid using the HttpServletRequest directly if at all possible. Use the ExternalContext instead.

          Stan

          • 2. Re: Graceful logout and friendly login ? How to?
            Basel Al-Mustafa Newbie

            Injecting UIViewRoot does not work.

            Caused by: org.jboss.seam.RequiredException: In attribute requires value for component: loginAction.view
             at org.jboss.seam.Component.getInstanceToInject(Component.java:1382)
             at org.jboss.seam.Component.injectFields(Component.java:1024)
             at org.jboss.seam.Component.inject(Component.java:795)
             at org.jboss.seam.interceptors.BijectionInterceptor.bijectTargetComponent(BijectionInterceptor.java:30)
            


            I also tried injecting the conversation object hoping that conversation.getViewId() would return the view name but without luck. I got the same RequiredException as with the UIViewRoot.

            @Stateless
            @Name("loginAction")
            public class LoginActionBean implements LoginAction{
             @In
             private UIViewRoot view;
            
             @In
             private Conversation conversation;
            
             @In(value="#{facesContext.externalContext.requestParameterMap}")
             private Map reqParam;
            }
            

            How can I get the UIViewRoot injected?

            Okay, I will use the "You've logged out" page for the logout action.

            • 3. Re: Graceful logout and friendly login ? How to?
              Basel Al-Mustafa Newbie

              Update: I managed to get the view id using two independent approaches:
              The first approach gets the view id from the request parameter map using the key "jsf_viewid". I am not sure whether this key is standard or specific to an implementation of JSF.

              @In(value="#{facesContext.externalContext.requestParameterMap}")
              private Map reqParam;
              
              public String login(){
               String viewId = reqParam.get("jsf_viewid").toString();
              }
              


              The second approach gets the view id from the UIViewRoot.
              @In
              private FacesContext facesContext;
              
              public String login(){
               UIViewRoot view = facesContext.getViewRoot();
               String viewId = view.getViewId();
              }
              


              Now I am left with one problem, that is getting the old GET request parameters from the URL as in http://localhost:8080/blogEntry.jsf?id=35. The reqParam map above contains the parameters passed by the POST request but not the old GET request.

              Is there a way to capture the current URL when the user clicks on login?