struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject Re[2]: what to store in session?
Date Wed, 26 Jun 2002 18:38:54 GMT


On Wed, 26 Jun 2002, Rick Reumann wrote:

> Date: Wed, 26 Jun 2002 14:19:52 -0400
> From: Rick Reumann <maillist@reumann.net>
> To: Craig R. McClanahan <craigmcc@apache.org>
> Cc: Struts Users Mailing List <struts-user@jakarta.apache.org>
> Subject: Re[2]: what to store in session?
>
> On Wednesday, June 26, 2002, 12:31:11 PM, Craig wrote:
>
> CRM> * Do not store complete data structures that are large and complex,
> CRM>   unless they really represent shared application data (in which case
> CRM>   they should probably be in the servlet context attributes instead).
>
> CRM> * Hide the caching choice you are making inside the get methods of your
> CRM>   user object, so you can change your mind later without modifying all
> CRM>   the code that uses the data.
>
>        I know this is probably a pretty newbie question, but...
>        How is it different storing something in the servlet context vs
>        having a static member in a class that is only loaded once
>        when null?

If the class defining this static variable is loaded from the webapp class
loader (/WEB-INF/classes or /WEB-INF/lib), there is not a lot of
difference (although in Servlet 2.3 you have the option to use context
attribute listeners to detect when attributes are added, removed, or
replaced).

If the class defining this static is loaded from a shared library
directory (i.e. something like common/lib in Tomcat), then there is only
one copy of the static variable for *all* webapps.

Context attributes are always global to the entire webapp, but never
shared across webapps, no matter how you organize your classes themselves.

>        In other words I'm tending to use your second
>        approach above, where say I need a list of StoreBeans I call a
>        getStores() from a Commons class that first checks if the
>        StoresList is null, and if it is null it loads them up.
>

That's a good plan.

My suggestion is to implement this logic inside a bean that hides whether
or not you are really caching the data or not -- say a StoresBean
something like this:

  public class StoresBean {

    public ArrayList stores = null;

    public synchronized Iterator getStores() {
        if (stores == null) {
            stores = new ArrayList();
            ... fill in the objects in this list ...
        }
        return (stores.iterator());
    }

  }

That way, the relevant stuff will get loaded the first time and then
reused.  But your calling application doesn't know that -- all it needs to
do is grab StoresBean out of the session attributes (if this is user
specific) or context attributes (if this is global), and call getStores().

>        Am I correct in assuming that subsequent requests by ANY other
>        session to the getStores() method will not load them up once
>        any session has called the method? If that assumption is
>        correct, is the only difference then in storing a List in the
>        servlet context a matter of being able to use the List on any
>        JSP page without having to set it there first in some action
>        class (as you would have to do with a List you got from a
>        getStores() method in some class)?
>

If the StoresBean bean is in session scope, then getStores() will go load
up the list once per user.  That makes sense, for example, if the list of
stores accessible to each user is different.  You would want to create
this bean, and store it as a session attribute, as part of your logon
processing -- or make it a property of the user bean if you are already
storing that in session scope.

If the StoresBean bean is in application scope (i.e. a servlet context
attribute), then getStores() will go load up the list the first time *any*
user requests it, then everyone will share.  This makes sense if the data
is global to all users.  You would want to create this bean as part of
your application startup, by either:

* In servlet 2.3, create a ServletContextListener and set it up
  in the contextCreated() method.

* In servlet 2.2 or later, create a servlet that is configured for
  load-on-startup, and set it up in the init() method.

* In servlet 2.2 or later, subclass the ActionServlet class in Struts,
  and override the init() method like this:

    public void init() throws ServletException {
        super.init();
        ... initialize context attributes here ...
    }

  and use this as the controller servlet.

>        Thanks for the help
>        Rick
>
>

Craig



--
To unsubscribe, e-mail:   <mailto:struts-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:struts-user-help@jakarta.apache.org>


Mime
View raw message