1 2 Previous Next 15 Replies Latest reply on Oct 24, 2010 1:23 PM by sykwitit

    Invalidate session on specific page

    sykwitit

      Hi Seam users,


      I am new to Seam and I have a question about invalidating a session on a specific page (in this case: a 'too busy-page'). Below you'll find an example of the sessionlistener i use.




      /**
      * Counts active sessions in the application and throws
      * <tt>TooBusyException</tt> when there are more users than a certain threshold.
      *
      */
      public class SessionListener implements HttpSessionListener, ServletContextListener {
          private int maximumNumberOfUsers;
          private static int numberOfUserSessions;
          /**
           * {@inheritDoc}
           */
          @Override
          public void contextDestroyed(ServletContextEvent sce) {
              // TODO Auto-generated method stub
          }

          /**
           * {@inheritDoc}
           */
          @Override
          public void contextInitialized(ServletContextEvent sce) {
              // TODO Auto-generated method stub
          }

          /**
           * {@inheritDoc}
           */
          @Override
          public synchronized void sessionCreated(HttpSessionEvent event) {
              Lifecycle.beginCall();
              numberOfUserSessions++;
              ApplicatieInstellingenService applicatieInstellingenService = (ApplicatieInstellingenService) Component.getInstance("applicatieInstellingenService");
              maximumNumberOfUsers = applicatieInstellingenService.findAllApplicatieInstellingen().get(0).getMaximumAantalBezoekers();
              if (numberOfUserSessions > maximumNumberOfUsers) {
                  System.out.println("=====================> Too many users, counter: " + numberOfUserSessions);
                  event.getSession().setMaxInactiveInterval(-1);
                  sessionDestroyed(event);
                  event.getSession().setAttribute("tooBusy", true);
              }
              System.out.println("=====================> Session created, counter: " + numberOfUserSessions);
          }

          /**
           * {@inheritDoc}
           */
          @Override
          public synchronized void sessionDestroyed(HttpSessionEvent event) {
              if (numberOfUserSessions > 0) {
                  numberOfUserSessions--;
              }
              System.out.println("=====================> Session destroyed, counter: " + numberOfUserSessions);
          }
          /**
           * {@inheritDoc}
           */
          @Observer(
          { "MaxSessionsUpdated" })
          public void log(int maximumAantalBezoekers) {
              this.maximumNumberOfUsers = maximumAantalBezoekers;
          }

          /**
           * {@inheritDoc}
           */
          public static int getNumberOfUserSessions() {
              return numberOfUserSessions;
          }
      }


      In this example I check if there are more sessions than a certain threshold(maximumNumberOfUsers). If this condition is true I redirect to a toobusy-page. Right now I use sessionDestroyed(event) to invalidate the session on the toobusy-page. I don't think this is the right solution. I have tried session.invalidate() and httpsession.invalidate(), but both didn't invalidate the session on the toobusy-page. What is the best way to invalidate the session on the toobusy-page? Thanks!

        • 1. Re: Invalidate session on specific page
          sykwitit

          Sorry, this is the code (formatted)


          public class SessionListener implements HttpSessionListener, ServletContextListener {
              private int maximumNumberOfUsers;
              private static int numberOfUserSessions;
              /**
               * {@inheritDoc}
               */
              @Override
              public void contextDestroyed(ServletContextEvent sce) {
                  // TODO Auto-generated method stub
              }
          
              /**
               * {@inheritDoc}
               */
              @Override
              public void contextInitialized(ServletContextEvent sce) {
                  // TODO Auto-generated method stub
              }
          
              /**
               * {@inheritDoc}
               */
              @Override
              public synchronized void sessionCreated(HttpSessionEvent event) {
                  Lifecycle.beginCall();
                  numberOfUserSessions++;
                  ApplicatieInstellingenService applicatieInstellingenService = (ApplicatieInstellingenService) Component.getInstance("applicatieInstellingenService");
                  maximumNumberOfUsers = applicatieInstellingenService.findAllApplicatieInstellingen().get(0).getMaximumAantalBezoekers();
                  if (numberOfUserSessions > maximumNumberOfUsers) {
                      System.out.println("=====================> Too many users, counter: " + numberOfUserSessions);
                      event.getSession().setMaxInactiveInterval(-1);
                      sessionDestroyed(event);
                      event.getSession().setAttribute("tooBusy", true);
                  }
                  System.out.println("=====================> Session created, counter: " + numberOfUserSessions);
              }
          
              /**
               * {@inheritDoc}
               */
              @Override
              public synchronized void sessionDestroyed(HttpSessionEvent event) {
                  if (numberOfUserSessions > 0) {
                      numberOfUserSessions--;
                  }
                  System.out.println("=====================> Session destroyed, counter: " + numberOfUserSessions);
              }
              /**
               * {@inheritDoc}
               */
              @Observer(
              { "MaxSessionsUpdated" })
              public void log(int maximumAantalBezoekers) {
                  this.maximumNumberOfUsers = maximumAantalBezoekers;
              }
          
              /**
               * {@inheritDoc}
               */
              public static int getNumberOfUserSessions() {
                  return numberOfUserSessions;
              }
          }






          • 2. Re: Invalidate session on specific page
            cash1981

            Why dont you have an action which is executed on the page where you want to invalidate the session that does exactly that.


            You can define that in pages.xml or page.xml

            • 3. Re: Invalidate session on specific page
              sykwitit

              Shervin Asgari wrote on Oct 21, 2010 04:08:


              Why dont you have an action which is executed on the page where you want to invalidate the session that does exactly that.

              You can define that in pages.xml or page.xml



              Hi Shervin,


              Thanks for your reply. Can you give me an example how to this? Thanks.


              Dhiradj

              • 4. Re: Invalidate session on specific page
                cash1981

                Well if I understand correctly you want when people enter too busy-page to invalidate session, and not before.


                So do you checks as before, and redirect to this page as normal.
                Then you create a too busy-page.page.xml file


                And in this file you write




                <action execute="#{session.invalidate}"/>



                • 5. Re: Invalidate session on specific page
                  sykwitit

                  Shervin Asgari wrote on Oct 21, 2010 04:16:


                  Well if I understand correctly you want when people enter too busy-page to invalidate session, and not before.

                  So do you checks as before, and redirect to this page as normal.
                  Then you create a too busy-page.page.xml file

                  And in this file you write



                  <action execute="#{session.invalidate}"/>






                  Hi Shervin,


                  I have tried this before and this gave me the following exception:


                  Session event listener threw exception
                  java.lang.IllegalStateException: Please end the HttpSession via org.jboss.seam.web.Session.instance().invalidate()



                  Thanks,
                  Dhiradj


                  • 6. Re: Invalidate session on specific page
                    cash1981

                    well then try



                    #{session.invalidate()} 





                    If this doesnt work, then I guess you can call a method that performs this



                    #{myComponent.killSession}
                    
                    public void killSession() {
                        org.jboss.seam.web.Session.instance().invalidate();
                    }



                    • 7. Re: Invalidate session on specific page
                      sykwitit

                      Shervin Asgari wrote on Oct 21, 2010 04:33:


                      well then try


                      #{session.invalidate()} 





                      If this doesnt work, then I guess you can call a method that performs this


                      #{myComponent.killSession}
                      
                      public void killSession() {
                          org.jboss.seam.web.Session.instance().invalidate();
                      }






                      Hi Shervin,


                      Thanks! The second option (killSession) invalidates the session(as i can see in the log). But now i'm redirected to the login-page (so a new session is created) in stead of the toobusy-page. Maybe because invalidating the session calls a sessionDestroyed()? How can i solve this issue? Thanks.

                      • 8. Re: Invalidate session on specific page
                        cash1981

                        This is most likely because the busy-page requires login.
                        Look in page.xml or pages.xml and set login-required to false.

                        • 9. Re: Invalidate session on specific page
                          sykwitit

                          Hi Shervin,


                          Thanks for your reply. login-required for the busy-page is set to false, but I still get the same problem.


                          Here's in example of the page.xml (toobusy-page):


                          <?xml version="1.0" encoding="UTF-8"?>
                          <page xmlns="http://jboss.com/products/seam/pages"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.1.xsd" 
                                login-required="false" 
                                scheme="https">
                          
                              <!-- Trigger logging of a page view -->
                              <action execute="#{killSessionComponent.killSession()}"/>  
                          </page>



                          • 10. Re: Invalidate session on specific page
                            cash1981

                            What about pages.xml? Have you looked there.


                            Maybe you have some code like




                            <page view-id="*" login-required="true">
                            



                            You need to see the path where your toobusy-page is, and see if you have defined that path to be login required in Pages.xml

                            • 11. Re: Invalidate session on specific page
                              sykwitit

                              This is how the toobusy-page is defined in pages.xml


                              <page view-id="/pages/register/*" scheme="https">
                                      <navigation>
                                          <rule if="#{not empty sessionContext.get('tooBusy') and sessionContext.get('tooBusy') == true}">
                                              <redirect view-id="/pages/register/public/toobusy.xhtml"/>
                                          </rule>
                                      </navigation>
                                      
                                      <navigation from-action="login">
                                          <redirect view-id="#{****}"/>
                                      </navigation>
                                      
                                      <navigation from-action="#{identity.logout}">
                                          <end-conversation before-redirect="true"/>
                                          <redirect view-id="****">
                                              <param name="****" value="logout" />
                                          </redirect>
                                      </navigation>
                                  </page>



                              • 12. Re: Invalidate session on specific page
                                ben_utzer
                                public class InvalidateSessionPhaseListener implements PhaseListener {
                                
                                     public void afterPhase(PhaseEvent event) {
                                          if (event.getFacesContext().getViewRoot().getViewId().equals(
                                                    "/toobusy.xhtml")) {
                                               ((HttpSession) event.getFacesContext().getExternalContext()
                                                              .getSession(false)).invalidate();
                                          }
                                     }
                                
                                     public void beforePhase(PhaseEvent event) {
                                
                                     }
                                
                                     public PhaseId getPhaseId() {
                                          return PhaseId.RENDER_RESPONSE;
                                     }
                                
                                }



                                • 13. Re: Invalidate session on specific page
                                  cash1981

                                  Try


                                  <page login-required="false" view-id="/pages/register/public/*">
                                  <navigation>
                                              <rule if="#{not empty sessionContext.get('tooBusy') and sessionContext.get('tooBusy') == true}">
                                                  <redirect view-id="/pages/register/public/toobusy.xhtml"/>
                                              </rule>
                                          </navigation>
                                  </page>
                                  


                                  Then you remove the other one.


                                  From the glance I can see the pages.xml looks a little strange.
                                  Remember that you cannot have a wildcard saying /pages/register/ is login required and
                                  then another saying /pages/register/public/
                                  is not login required.


                                  I am at least not sure what will happen.

                                  • 14. Re: Invalidate session on specific page
                                    cash1981

                                    Also make sure you dont have @Restrict on your component which is killing the session

                                    1 2 Previous Next