You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by "Molitor, Stephen" <SM...@erac.com> on 2001/09/28 01:07:18 UTC

Request / Session Scoped Beans, Best Practices

Hi.  We've been using Struts for a few weeks now, and we're looking for
advice on when to use session versus request scoped objects.  So far, our
policy has been to use request scoped objects by default, except when that's
not convenient.  If we find that we need to remember the same ActionForm or
read-only value bean on more than one page, we stick it in session scope.
We have a lot of session scoped objects.  However, we're worried that this
won't scale very well.  We understand that session scoped objects are
totally appropriate for many cases; we just feel that we are over using
them, and need a better way to manage them.

First there's the memory issue -- as our app gets bigger, we will have more
and more session scoped objects lying around.  We can use
HttpSession.removeAttribute to clean up objects we no longer need, but it
can be tricky to make sure that all paths lead back to the removeAttribute
call.  

More important is the maintenance and name clash issue.  For ActionForms, we
avoid having two forms with the same name, since they're all specified in
the struts config file, and it won't allow us to define two forms with the
same name.  That's great.  However, for read-only value beans, we have just
been hard-coding the attribute names in the Actions and JSP pages.  A year
from now, a new developer might be working on a new piece of the app, and
accidentally pick the same name as an older session scoped value bean,
stomping on the older bean.  Session attribute names are like global
variables (global to one user, anyway), and seem to have all the problems
associated with global variables.  So, how do people manage them?  A
constants file/interface?  What about naming conventions?  We've been using
short little names, like 'vehicleTypeList', but perhaps a package style
naming convention would help prevent clashes.  For example
'vehicles.vehicleTypeList', or something.

One situation where we need session value beans is on pages that have read
only dynamic data (drop-down lists, headers, etc.) in addition to input form
data that is validated by the ActionServlet via the derived
ActionForm.validate method.  We originally put these read-only value beans
in request scope, since we figured we only needed them for one request.
However, we found that if the ActionForm validation failed, these value
beans were no longer there when the controller returned us to the same page
after a validation error.  This caused the JSP to blow up with a null
pointer exception.   So we put these value beans in session scope.  Another
alternative would have been to put all the read only data into the
ActionForm.  This didn't seem very clean, however, as the read-only data
didn't have much to do with the input data form.  Any other alternatives?

What alternatives are there to session scoped beans?  One could use hidden
variables to pass along simple data items, but that becomes awkward for
storing lots of fields, or whole objects, as you have to unpack them in the
JSP and pack them back up in the next Action.  Perhaps there could be some
sort of scope between request and session, where your object would be
forgotten at the end of the request, unless you explicitly 'renewed' it in
your Action.  If you did something like
'servlet.getRenewables().renew("myObjectKey")', the object would be
available in the next request via
'servlet.getRenewables().getAttribute("myObjectKey")'; if you didn't make
the 'renew' call, it would be forgotten.  This way you wouldn't have to
worry about explicitly removing it from the session.  It might be a nice
alternative to session in some cases.  It could be implented either by
schlepping stuff along via hidden variables, or by having the servlet or
some base action maintain a session scoped map of 'renewables'.  At the end
of every action, all objects in 'renewables' would be removed, except those
that were explicitly renewed.  (This probably wouldn't help with the problem
described in the previous paragraph, unless the ActionServlet did not clear
out the 'renewables' map after a validation error.)

But I digress.  We're looking on advice on managing session scoped objects,
or alternatives to session scoped objects.  Any help would be greatly
appreciated.

Thanks!

Steve Molitor
smolitor@erac.com

Re: Request / Session Scoped Beans, Best Practices

Posted by Ted Husted <hu...@apache.org>.
The Workflow proposal, being handled jointly in the Commons and Struts,
may be of some help. It adds a "Context" that can be used to manage
"temporary" session attributes. Each context also has it's own naming
scope, so that would help with the conflicts. 

Another alternative is to put your own manager in the session to watch
over your beans. This could just be a HashMap subclass with some extra
methods. For example, one method to add a new property and another to
change it, so developers don't stomp on each other. It could also be set
to watch the memory usuage, and be able to automatically dispose "stale"
properties to make room for new ones. Which is to say, if you feel a
need for another context, then create one. The default versions are
little more than hashmaps anyway.

Stealing a page from the workflow proposal, your manager might have an
extra property for a "scope". Then you could add the properties with the
drop down lists with the same scope token. When the process was
complete, the manager could dispose all the properties with the same
scope at once. A scope property may also help with naming conflicts. 

I would opt for attribute names that fully identified it using the
package name, but abbreviated in the code with a short static, so you
don't have to worry about typing errors ;-)

public static final String DROP_DOWN_KEY =
"com.husted.application.package.class.dropdown";

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel +1 716 737-3463
-- http://www.husted.com/about/struts/


"Molitor, Stephen" wrote:
> 
> Hi.  We've been using Struts for a few weeks now, and we're looking for
> advice on when to use session versus request scoped objects.  So far, our
> policy has been to use request scoped objects by default, except when that's
> not convenient.  If we find that we need to remember the same ActionForm or
> read-only value bean on more than one page, we stick it in session scope.
> We have a lot of session scoped objects.  However, we're worried that this
> won't scale very well.  We understand that session scoped objects are
> totally appropriate for many cases; we just feel that we are over using
> them, and need a better way to manage them.
> 
> First there's the memory issue -- as our app gets bigger, we will have more
> and more session scoped objects lying around.  We can use
> HttpSession.removeAttribute to clean up objects we no longer need, but it
> can be tricky to make sure that all paths lead back to the removeAttribute
> call.
> 
> More important is the maintenance and name clash issue.  For ActionForms, we
> avoid having two forms with the same name, since they're all specified in
> the struts config file, and it won't allow us to define two forms with the
> same name.  That's great.  However, for read-only value beans, we have just
> been hard-coding the attribute names in the Actions and JSP pages.  A year
> from now, a new developer might be working on a new piece of the app, and
> accidentally pick the same name as an older session scoped value bean,
> stomping on the older bean.  Session attribute names are like global
> variables (global to one user, anyway), and seem to have all the problems
> associated with global variables.  So, how do people manage them?  A
> constants file/interface?  What about naming conventions?  We've been using
> short little names, like 'vehicleTypeList', but perhaps a package style
> naming convention would help prevent clashes.  For example
> 'vehicles.vehicleTypeList', or something.
> 
> One situation where we need session value beans is on pages that have read
> only dynamic data (drop-down lists, headers, etc.) in addition to input form
> data that is validated by the ActionServlet via the derived
> ActionForm.validate method.  We originally put these read-only value beans
> in request scope, since we figured we only needed them for one request.
> However, we found that if the ActionForm validation failed, these value
> beans were no longer there when the controller returned us to the same page
> after a validation error.  This caused the JSP to blow up with a null
> pointer exception.   So we put these value beans in session scope.  Another
> alternative would have been to put all the read only data into the
> ActionForm.  This didn't seem very clean, however, as the read-only data
> didn't have much to do with the input data form.  Any other alternatives?
> 
> What alternatives are there to session scoped beans?  One could use hidden
> variables to pass along simple data items, but that becomes awkward for
> storing lots of fields, or whole objects, as you have to unpack them in the
> JSP and pack them back up in the next Action.  Perhaps there could be some
> sort of scope between request and session, where your object would be
> forgotten at the end of the request, unless you explicitly 'renewed' it in
> your Action.  If you did something like
> 'servlet.getRenewables().renew("myObjectKey")', the object would be
> available in the next request via
> 'servlet.getRenewables().getAttribute("myObjectKey")'; if you didn't make
> the 'renew' call, it would be forgotten.  This way you wouldn't have to
> worry about explicitly removing it from the session.  It might be a nice
> alternative to session in some cases.  It could be implented either by
> schlepping stuff along via hidden variables, or by having the servlet or
> some base action maintain a session scoped map of 'renewables'.  At the end
> of every action, all objects in 'renewables' would be removed, except those
> that were explicitly renewed.  (This probably wouldn't help with the problem
> described in the previous paragraph, unless the ActionServlet did not clear
> out the 'renewables' map after a validation error.)
> 
> But I digress.  We're looking on advice on managing session scoped objects,
> or alternatives to session scoped objects.  Any help would be greatly
> appreciated.
> 
> Thanks!
> 
> Steve Molitor
> smolitor@erac.com

Re: Request / Session Scoped Beans, Best Practices

Posted by Renaud Waldura <re...@waldura.org>.
Hi Stephen,

I read your comments with interest.


> What alternatives are there to session scoped beans?  One could use hidden
> variables to pass along simple data items, but that becomes awkward for
> storing lots of fields, or whole objects, as you have to unpack them in
the
> JSP and pack them back up in the next Action.  Perhaps there could be some

Our application is made from many wizard-type dialogs; instead of storing
the action form bean in the session, we decided to have it stored in the
request only, and propagate it from form to form (the steps of the wizard)
using the technique you describe of serializing the form bean to a hidden
field.

All the work is done by a subclass of ActionServlet, resulting in "clean
pages" -- identical to ones using a session-stored form bean. It's really
easy to use. Overall I feel like it's a valid approach, but heavy in terms
of processing: the form bean is serialized/deserialized at every request.
I'm starting to think your "sub-session" scope could be a better approach.


Regarding the scope issue, we also try to organize the (otherwise flat)
action namespace by naming the actions according to the stuff they do, and
where they are called. E.g. in a wizard "downloadSoftware", a sample step
(and the corresponding action) is named
"/downloadSoftware/enterProxyParams.do". The ordering of the steps, and how
they relate to each other, is done solely inside struts-config.xml.


--Renaud