If your looking for something to run WHEN a session expires, the better choice
is probably a SessionListener. I'm not clear on if that's what you really want
though. Assuming it is, here's an example from one of my apps... this
basically updates a list of active users in a static member of a class that
stores application statics, as well as some other statistical updates...
package com.mycompany.myapp.listeners;
import com.mycompany.myapp.stats.AppStats;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionListener implements HttpSessionListener {
public synchronized void sessionCreated(HttpSessionEvent se) {
cleanupActiveUsersList();
HashMap appStats = (HashMap)AppStats.getStats();
HashMap activeUsers = (HashMap)appStats.get("activeUsers");
synchronized (activeUsers) {
activeUsers.put(se.getSession().getId(), new HashMap());
int currentCount = activeUsers.size();
BigDecimal maxSimultaneousUsers =
(BigDecimal)appStats.get("maxSimultaneousUsers");
BigDecimal maxSimultaneousUsersRunning =
(BigDecimal)appStats.get("maxSimultaneousUsersRunning");
if (currentCount > maxSimultaneousUsers.intValue()) {
appStats.put("maxSimultaneousUsers", new BigDecimal(currentCount));
}
if (currentCount > maxSimultaneousUsersRunning.intValue()) {
appStats.put("maxSimultaneousUsersRunning", new
BigDecimal(currentCount));
}
appStats.put("activeUsers", activeUsers);
}
AppStats.setStats(appStats);
} // End sessionCreated()
public synchronized void sessionDestroyed(HttpSessionEvent se) {
String sessionID = se.getSession().getId();
cleanupActiveUsersList();
HashMap appStats = (HashMap)AppStats.getStats();
HashMap activeUsers = (HashMap)appStats.get("activeUsers");
synchronized (activeUsers) {
activeUsers.remove(se.getSession().getId());
appStats.put("activeUsers", activeUsers);
}
AppStats.setStats(appStats);
} // End sessionDestroyed
public synchronized static void cleanupActiveUsersList() {
HashMap appStats = (HashMap)AppStats.getStats();
HashMap activeUsers = (HashMap)appStats.get("activeUsers");
synchronized (activeUsers) {
for (Iterator it = activeUsers.keySet().iterator(); it.hasNext();) {
String uiKey = (String)it.next();
HashMap hm = (HashMap)activeUsers.get(uiKey);
String userID = (String)hm.get("userID");
if (userID == null) {
activeUsers.remove(uiKey);
}
}
appStats.put("activeUsers", activeUsers);
}
AppStats.setStats(appStats);
} // End cleanupActiveUsersList()
} // End class
--
Frank W. Zammetti
Founder and Chief Software Architect
Omnytex Technologies
http://www.omnytex.com
On Thu, January 20, 2005 2:08 pm, Dakota Jack said:
> That's right. And, that is what I provided. There is an error in the
> ServletExpireFilter I provided, however. You have to change
> filterConfig = filterConfig to this.filterConfig = filterConfig in two
> places. Then it works like a charm.
>
> Jack
>
>
> On Thu, 20 Jan 2005 10:05:51 -0800, Wiebe de Jong <[EMAIL PROTECTED]> wrote:
>> This will detect that a session has already expired, but I think that is
>> not
>> what he wants.
>>
>> I think Jack is looking for something to run WHEN the session expires,
>> similar to the destroy() method in a plugin that runs when the
>> application
>> stops.
>>
>> Wiebe de Jong
>>
>> -----Original Message-----
>> From: Amleto Di Salle [mailto:[EMAIL PROTECTED]
>> Sent: Thursday, January 20, 2005 9:41 AM
>> To: 'Struts Users Mailing List'; 'Dakota Jack'
>> Subject: R: R: Session Strategy (here's a filter)
>>
>> Hello Jack,
>> you detect a session expiration using the getSession( false ) method. If
>> you use false, the session is not created if there is no current
>> session.
>> In fact, in a previous e-mail that I sent, there was my Filter which
>> used the getSession method.
>> All it works if the session expires, and you have to set in some way the
>> web container in order to delete the session object.
>>
>> So, I don't understand what do you mean "I am not looking to create a
>> timeout but to detect a session expiration, so that the user can be
>> redirected to a page".
>>
>> BR
>> /Amleto
>>
>> > -----Messaggio originale-----
>> > Da: Dakota Jack [mailto:[EMAIL PROTECTED]
>> > Inviato: gioved? 20 gennaio 2005 18.03
>> > A: Amleto Di Salle
>> > Cc: Struts Users Mailing List
>> > Oggetto: Re: R: Session Strategy (here's a filter)
>> >
>> >
>> > Hello, Amleto,
>> >
>> > I am not looking to create a timeout but to detect a session
>> > expiration, so that the user can be redirected to a page. I
>> > am not, that is, looking to get rid of people but looking to
>> > help people that have their session expired.
>> >
>> > Jack
>> >
>> >
>> > On Thu, 20 Jan 2005 17:42:55 +0100, Amleto Di Salle
>> > <[EMAIL PROTECTED]> wrote:
>> > > You can do this using request.getSession( false ) (false doesn't
>> > > create the session) and use the following in the tag in the web.xml.
>> > >
>> > > <session-config>
>> > > <session-timeout>30</session-timeout>
>> > > </session-config>
>> > > 30 are minutes
>> > >
>> > > You can set the session-timeout also in the web container
>> > (see tomcat
>> > > documentation).
>> > >
>> > > BR
>> > > /Amleto
>> > >
>> > > > -----Messaggio originale-----
>> > > > Da: Dakota Jack [mailto:[EMAIL PROTECTED]
>> > > > Inviato: gioved? 20 gennaio 2005 17.08
>> > > > A: Struts Users Mailing List
>> > > > Oggetto: Re: Session Strategy (here's a filter)
>> > > >
>> > > >
>> > > > I was looking for a filter that detected sessions that
>> > had expired
>> > > > and rerouted the request to a login or other appropriate page.
>> > > >
>> > > > Jack
>> > > >
>> > > >
>> > > > On Thu, 20 Jan 2005 10:53:09 -0500, [EMAIL PROTECTED]
>> > > > <[EMAIL PROTECTED]> wrote:
>> > > > > Here's the filter I use. It contains some logging that you
>> > > > can choose
>> > > > > to ignore and I also set some session attributes that I use for
>> > > > > navigation AFTER the re-login, to get the user back to the
>> > > > page they
>> > > > > were on or as near as possible, given only their first/last
>> > > > name and
>> > > > > password. I also included the configuration I added to
>> > my web.xml
>> > > > > file to activate the filter for all actions beginning with
>> > > > "/secure/"
>> > > > > Then, I added "/secure/" to all actions that should use the
>> > > > filter. I
>> > > > > did this for all actions except the following, for which it
>> > > > would have
>> > > > > introduced a pretty obvious logic error: login,
>> > register, and an
>> > > > > action I use to direct the user back to the page they were
>> > > > on before
>> > > > > the timeout.
>> > > > >
>> > > > > Here's the filter
>> > > > >
>> > > >
>> > ********************************************************************
>> > > > **
>> > > > > *********************************
>> > > > >
>> > > > >
>> > > >
>> > /*******************************************************************
>> > > > **
>> > > > > *******
>> > > > > *
>> > > > > * This class provides a servlet filter ensure that each
>> > > > request is coming
>> > > > > from
>> > > > > * an authenticated user. It also logs each servlet invocation.
>> > > > > *
>> > > > >
>> > > > >
>> > > >
>> > ********************************************************************
>> > > > **
>> > > > > ******/
>> > > > > package schs82;
>> > > > >
>> > > > > import java.util.*;
>> > > > > import javax.servlet.*;
>> > > > > import javax.servlet.http.*;
>> > > > > import org.apache.struts.action.*;
>> > > > > import org.apache.commons.logging.Log;
>> > > > > import org.apache.commons.logging.LogFactory;
>> > > > > import java.text.DateFormat;
>> > > > > import schs82.*;
>> > > > >
>> > > > > public final class AuthenticationFilter implements Filter {
>> > > > >
>> > > > > private Log logger;
>> > > > >
>> > > > > public void init(javax.servlet.FilterConfig filterConfig)
>> > > > > throws javax.servlet.ServletException {
>> > > > >
>> > > > > logger = LogFactory.getLog("SCHS82");
>> > > > > }
>> > > > >
>> > > > > public void doFilter(javax.servlet.ServletRequest request,
>> > > > > javax.servlet.ServletResponse response,
>> > > > > javax.servlet.FilterChain filterChain)
>> > > > > throws java.io.IOException,
>> > > > > javax.servlet.ServletException {
>> > > > >
>> > > > > HttpServletRequest req = (HttpServletRequest)request;
>> > > > > HttpServletResponse resp > >
>> (HttpServletResponse)response;
>> > > > >
>> > > > > HttpSession session = req.getSession();
>> > > > > String firstName > > > >
>> (String)session.getAttribute("firstName");
>> > > > > String lastName > >
>> (String)session.getAttribute("lastName");
>> > > > > String password > >
>> (String)session.getAttribute("password");
>> > > > > String currentAction = req.getRequestURI();
>> > > > > session.setAttribute("currentAction", currentAction);
>> > > > > session.setAttribute("currentActionDisposition", "");
>> > > > > session.setAttribute("currentActionMessage", "");
>> > > > >
>> > > > > if (logger.isInfoEnabled()) {
>> > > > > // log each servlet invoked, date/time and user
>> > > > who invoked
>> > > > > GregorianCalendar calendar = new
>> > GregorianCalendar();
>> > > > > java.util.Date dateTime = calendar.getTime();
>> > > > > DateFormat format > > > > >
>> DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
>> > DateFormat.LONG);
>> > > > > String now = format.format(dateTime);
>> > > > >
>> > > > > logger.info(" " + now
>> > > > > + " User: " + firstName
>> > > > > + " " + lastName
>> > > > > + ", Servlet: " + currentAction);
>> > > > > }
>> > > > >
>> > > > > if (session.isNew()) {
>> > > > > // session timed-out
>> > > > > session.setAttribute("currentActionDisposition",
>> > > > > "sessionTimeout");
>> > > > >
>> > session.setAttribute("currentActionMessage", "You were
>> > > > > inactive" +
>> > > > > " too long, so you must
>> > > > login again!
>> > > > > Please" +
>> > > > > " click on the button
>> > > > below to go to
>> > > > > the"
>> > > > > +
>> > > > > " login page.");
>> > > > >
>> > > > >
>> > > > resp.sendRedirect("/schs82/BuildActionResultViewAction.do");
>> > > > > }
>> > > > > else if (firstName == null || lastName == null ||
>> > > > password => > > > > null) {
>> > > > > if (logger.isInfoEnabled()) {
>> > > > > logger.info("NON-AUTHENTICATED USER
>> > ATTEMPTED TO
>> > > > > ACCESS SCHS82 "
>> > > > > + "APPLICATION! (Session
>> > > > attributes = Null)");
>> > > > > }
>> > > > > session.setAttribute("currentActionDisposition",
>> > > > > "systemError");
>> > > > >
>> > session.setAttribute("currentActionMessage", "You have
>> > > > > accessed" +
>> > > > > " SCHS82.com in a
>> > > > non-authorized way.
>> > > > > Please" +
>> > > > > " click on the button
>> > > > below to go to
>> > > > > the"
>> > > > > +
>> > > > > " login page.");
>> > > > >
>> > > > >
>> > > > resp.sendRedirect("/schs82/BuildActionResultViewAction.do");
>> > > > > }
>> > > > > else {
>> > > > > //authenticate user
>> > > > > User user = new User();
>> > > > > user.setFirstName(firstName);
>> > > > > user.setLastName(lastName);
>> > > > > user.setPassword(password);
>> > > > > if (user.checkAuthorization()) {
>> > > > > //user is authentic
>> > > > > filterChain.doFilter(request, response);
>> > > > > }
>> > > > > else {
>> > > > > //user is NOT authentic
>> > > > > if (logger.isInfoEnabled()) {
>> > > > > logger.info("NON-AUTHENTICATED USER
>> > > > ATTEMPTED TO
>> > > > > ACCESS "
>> > > > > + "SCHS82 APPLICATION!
>> > (Invalid name
>> > > > > or password)");
>> > > > > }
>> > > > > session.setAttribute("currentActionDisposition",
>> > > > > "systemError");
>> > > > >
>> > > > session.setAttribute("currentActionMessage", "You have
>> > > > > accessed" +
>> > > > > " SCHS82.com in a
>> > > > non-authorized
>> > > > > way. Please" +
>> > > > > " click on the button
>> > > > below to go
>> > > > > to the" +
>> > > > > " login page.");
>> > > > >
>> > > > > resp.sendRedirect("/schs82/BuildActionResultViewAction.do");
>> > > > > }
>> > > > > }
>> > > > > }
>> > > > >
>> > > > > public void destroy() {}
>> > > > > }
>> > > > >
>> > > > > And this must be added to web.xml
>> > > > >
>> > > >
>> > ********************************************************************
>> > > > **
>> > > > > *********************************
>> > > > >
>> > > > > <filter>
>> > > > > <filter-name>AuthenticationFilter</filter-name>
>> > > > > <filter-class>schs82.AuthenticationFilter</filter-class>
>> > > > > </filter>
>> > > > >
>> > > > > <filter-mapping>
>> > > > > <filter-name>AuthenticationFilter</filter-name>
>> > > > > <url-pattern>/secure/*</url-pattern>
>> > > > > </filter-mapping>
>> > > > >
>> > > > > Dakota Jack <[EMAIL PROTECTED]>
>> > > > > 01/20/2005 09:53 AM
>> > > > > Please respond to "Struts Users Mailing List"
>> > > > >
>> > > > > To: Struts Users Mailing List
>> > <[email protected]>,
>> > > > > [EMAIL PROTECTED]
>> > > > > cc:
>> > > > > Subject: Re: Session Strategy
>> > > > >
>> > > > > I am also too lazy to make a filter! LOL ;-) Anyone
>> > have one of
>> > > > > these in their toolbox they would like to share?
>> > > > >
>> > > > > Jack
>> > > > >
>> > > > > On Thu, 20 Jan 2005 12:49:41 +0800, Andrew Hill
>> > > > > <[EMAIL PROTECTED]> wrote:
>> > > > > > Id support the filter suggestion, though for myself I
>> > > > generally do
>> > > > > > the check in the RequestProcessor, as Ive usually
>> > > > overrideen it to
>> > > > > > perform other evil anyhow, and Im lazy to make a filter.
>> > > > > >
>> > > > > > If you dont keep your JSP under WEB-INF (IMHO thats
>> > where they
>> > > > > > belong because they are 'code & config' , just like your
>> > > > > > classes,jars, and struts-config.xml and tlds) then you should
>> > > > > > declare some sort of security constraint so they can only
>> > > > be reached
>> > > > > > by a server side forward from their respective preperation
>> > > > > > action.
>> > > > > >
>> > > > > >
>> > > > > > Frank W. Zammetti wrote:
>> > > > > >
>> > > > > > > If the user clicks a button, you are either going to (a) go
>> > > > > > > directly
>> > > > > to
>> > > > > > > a JSP, which is generally not a good idea in a Struts-based
>> > > > > application
>> > > > > > > anyway (or any servlet-based application for that
>> > > > matter) or (b)
>> > > > > > > go to an Action, as you probably should be doing. In
>> > > > either case,
>> > > > > > > choice 1
>> > > > > is
>> > > > > > > what I would do personally. Putting things under
>> > > > WEB-INF as David
>> > > > > > > suggests works great, but it just feels kind of wrong to me.
>> > > > > > >
>> > > > > > > You'll also want to call some common code from all your
>> > > > > > > Actions that does the same basic check and forwards
>> > > > > > > immediately to your "logon
>> > > > > again"
>> > > > > > > page. I do this by means of an ActionHelpers class
>> > that has
>> > > > > > > two
>> > > > > static
>> > > > > > > methods, start() and finish() that are called, as
>> > I'm sure you
>> > > > > > > could guess, at the start and end of all my Actions.
>> > > > They do some
>> > > > > > > common tasks, including this check.
>> > > > > > >
>> > > > > > > If you want a real solution though, externalize
>> > your security
>> > > > > > > using something like Netegrity Siteminder. It will
>> > > > deal with this
>> > > > > > > situation for you, in a theoretically more secure
>> > > > fashion than you
>> > > > > > > could
>> > > > > probably
>> > > > > > > do on your own.
>> > > > > > >
>> > > > > > > Yet another idea is a filter that will check if a
>> > > > session is alive
>> > > > > > > and redirect as appropriate. This I believe can work no
>> > > > > > > matter what your request is to (Action or JSP directly), or
>> > > > > > > any other resource,
>> > > > > assuming
>> > > > > > > the app server serves everything.
>> > > > > > >
>> > > > > >
>> > > > > >
>> > > >
>> > --------------------------------------------------------------------
>> > > > > > -
>> > > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>> > > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>> > > > > >
>> > > > > >
>> > > > >
>> > > > > --
>> > > > > ------------------------------
>> > > > >
>> > > > > "You can lead a horse to water but you cannot make it
>> > float on its
>> > > > > back."
>> > > > >
>> > > > > ~Dakota Jack~
>> > > > >
>> > > > > "You can't wake a person who is pretending to be asleep."
>> > > > >
>> > > > > ~Native Proverb~
>> > > > >
>> > > > > "Each man is good in His sight. It is not necessary for
>> > > > eagles to be
>> > > > > crows."
>> > > > >
>> > > > > ~Hunkesni (Sitting Bull), Hunkpapa Sioux~
>> > > > >
>> > > > > -----------------------------------------------
>> > > > >
>> > > > > "This message may contain confidential and/or privileged
>> > > > information.
>> > > > > If you are not the addressee or authorized to receive
>> > this for the
>> > > > > addressee, you must not use, copy, disclose, or take any
>> > > > action based
>> > > > > on this message or any information herein. If you have
>> > > > received this
>> > > > > message in error, please advise the sender immediately by
>> > > > reply e-mail
>> > > > > and delete this message. Thank you for your cooperation."
>> > > > >
>> > > > >
>> > > >
>> > --------------------------------------------------------------------
>> > > > -
>> > > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>> > > > > For additional commands, e-mail: [EMAIL PROTECTED]
>> > > > >
>> > > > >
>> > > >
>> > > >
>> > > > --
>> > > > ------------------------------
>> > > >
>> > > > "You can lead a horse to water but you cannot make it
>> > float on its
>> > > > back."
>> > > >
>> > > > ~Dakota Jack~
>> > > >
>> > > > "You can't wake a person who is pretending to be asleep."
>> > > >
>> > > > ~Native Proverb~
>> > > >
>> > > > "Each man is good in His sight. It is not necessary for
>> > eagles to be
>> > > > crows."
>> > > >
>> > > > ~Hunkesni (Sitting Bull), Hunkpapa Sioux~
>> > > >
>> > > > -----------------------------------------------
>> > > >
>> > > > "This message may contain confidential and/or privileged
>> > > > information. If you are not the addressee or authorized
>> > to receive
>> > > > this for the addressee, you must not use, copy, disclose, or take
>> > > > any action based on this message or any information
>> > herein. If you
>> > > > have received this message in error, please advise the sender
>> > > > immediately by reply e-mail and delete this message.
>> > Thank you for
>> > > > your cooperation."
>> > > >
>> > > >
>> > --------------------------------------------------------------------
>> > > > -
>> > > > To unsubscribe, e-mail: [EMAIL PROTECTED]
>> > > > For additional commands, e-mail: [EMAIL PROTECTED]
>> > > >
>> > > > --
>> > > > No virus found in this incoming message.
>> > > > Checked by AVG Anti-Virus.
>> > > > Version: 7.0.300 / Virus Database: 265.7.0 - Release Date:
>> > > > 17/01/2005
>> > > >
>> > > >
>> > >
>> > > --
>> > > No virus found in this outgoing message.
>> > > Checked by AVG Anti-Virus.
>> > > Version: 7.0.300 / Virus Database: 265.7.0 - Release Date:
>> > 17/01/2005
>> > >
>> > >
>> >
>> >
>> > --
>> > ------------------------------
>> >
>> > "You can lead a horse to water but you cannot make it float
>> > on its back."
>> >
>> > ~Dakota Jack~
>> >
>> > "You can't wake a person who is pretending to be asleep."
>> >
>> > ~Native Proverb~
>> >
>> > "Each man is good in His sight. It is not necessary for
>> > eagles to be crows."
>> >
>> > ~Hunkesni (Sitting Bull), Hunkpapa Sioux~
>> >
>> > -----------------------------------------------
>> >
>> > "This message may contain confidential and/or privileged
>> > information. If you are not the addressee or authorized to
>> > receive this for the addressee, you must not use, copy,
>> > disclose, or take any action based on this message or any
>> > information herein. If you have received this message in
>> > error, please advise the sender immediately by reply e-mail
>> > and delete this message. Thank you for your cooperation."
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: [EMAIL PROTECTED]
>> > For additional commands, e-mail: [EMAIL PROTECTED]
>> >
>> >
>> > --
>> > No virus found in this incoming message.
>> > Checked by AVG Anti-Virus.
>> > Version: 7.0.300 / Virus Database: 265.7.0 - Release Date: 17/01/2005
>> >
>> >
>>
>> --
>> No virus found in this outgoing message.
>> Checked by AVG Anti-Virus.
>> Version: 7.0.300 / Virus Database: 265.7.0 - Release Date: 17/01/2005
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>>
>
>
> --
> ------------------------------
>
> "You can lead a horse to water but you cannot make it float on its back."
>
> ~Dakota Jack~
>
> "You can't wake a person who is pretending to be asleep."
>
> ~Native Proverb~
>
> "Each man is good in His sight. It is not necessary for eagles to be
> crows."
>
> ~Hunkesni (Sitting Bull), Hunkpapa Sioux~
>
> -----------------------------------------------
>
> "This message may contain confidential and/or privileged information.
> If you are not the addressee or authorized to receive this for the
> addressee, you must not use, copy, disclose, or take any action based
> on this message or any information herein. If you have received this
> message in error, please advise the sender immediately by reply e-mail
> and delete this message. Thank you for your cooperation."
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]