You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Christina Siena <cs...@mountaincable.net> on 2004/07/07 04:43:20 UTC

some best practices questions

I recently developed an application with a complex UI. One of the pages required querying the database based on user selection and re-displaying the page with the retrieved data and any previous existing user selections. Four different fields can trigger a db query resulting in page re-display and validations can also result in page re-display. Each time the page is re-displayed, the "state" of the page must be "remembered" from the last time it was displayed. (still with me so far?) Most of the data retrieved is list data displayed in single- or multi-select lists and populated using html:options collection and LabelValueBean. (for those of you reading this post who have developed similar code, you will know what I'm referring to).

In the action, the retrieved data is placed in session scope to minimize db hits. I thought this was a good idea at the time. For some reason, placing data in session scope is frowned upon by some members of my team (even if improves performance). Anyways, what I need are some ideas of the best practices that fellow Struts users follow when a page requires querying the db and re-displaying the page with the retrieved data and previous selections if placing the data in session scope is not an option. How can I recall the previously retrieved data without requerying the db? Would it make sense to hide the data in the page? (i.e. either using hidden fields or hidden select lists or to generate a JavaScript array). What are the risks, if any, of hiding the data in the page? (i.e. performance).

If anyone has developed similar pages, can you tell me if you decided for or against placing data in session scope and why?

Any ideas would be appreciated.

Thanks in advance.

Re: some best practices questions

Posted by Ted Husted <hu...@apache.org>.
Essentially, this is what ASP.NET does by default. The original values for the controls that you want to persist are encoded and serialized and written to the form as a single hidden variable. Then on the server side, it unmarshalls the hidden variable and restores the controls to their original state. Any request parameters are then applied so update the controls to their new values. 

IMHO, it would be very useful to have a tag that serialized the ActionForm so that you would have a copy of its prior state. Ideally, the request processor would first repopulate the ActionForm from the serialized copy, and then look to the request parameters (a la .NET). 

Or course, there is no free lunch. You save on the server, but you pay on the client, since all this serialized data has to be rendered by your browser. But, it would avoid over-using session scope.

-Ted.

On Wed, 07 Jul 2004 22:46:04 -0400, Christina Siena wrote:
> I have an idea how to persist the data that I currently place in
> session scope but I need to run it by someone.
>
>
> Recall when I said that placing data in session scope is frowned
> upon by some members of my team? Well no one said anything about
> not using Java serialization. Why couldn't I serialize the
> same data that I currently keep in session scope? I've already
> implemented a solution for streaming images so creating a temp file
> should not be a problem. Here is what I think I will need:
>
>
> In the action where the data is first retrieved:
>
>
> try {
> final String prefix = "myVehicleLineMap";
> final String suffix = null;
> File file = File.createTempFile(prefix, suffix); FileOutputStream
> fileOutputStream = new FileOutputStream(file); ObjectOutputStream
> objectOutputStream = new ObjectOutputStream(fileOutputStream);
> objectOutputStream.writeObject(myMap); objectOutputStream.flush();
> myForm.setTempFileName(file.getAbsolutePath()); } catch (Exception
> e) {
> System.out.println(this.getClass().getName() + "==>> " +
> e.toString()); }
>
> In the action where the data needs to be re-accessed to prepare the
> page for re-display:
>
>
> try {
>
>
> FileInputStream fileInputStream = new
> FileInputStream(myForm.getTempFileName()); ObjectInputStream
> objectInputStream = new ObjectInputStream(fileInputStream);
> SortedMap myMap = (SortedMap) objectInputStream.readObject(); //
> use myMap as before (when in session scope) } catch (Exception e) {
> System.out.println(this.getClass().getName() + "==>> " +
> e.toString()); }
>
> This is just an idea at this point, so I would welcome any
> feedback. I'm not sure if this will work or if its feasible, but at
> least it may generate some more ideas.
>
>
> ----- Original Message -----
> From: Michael McGrady
> To: Struts Users Mailing List
> Sent: Tuesday, July 06, 2004 11:59 PM
> Subject: Re: some best practices questions
>
>
> Ever thought about creating a new scope managed by your own manager
> from application scope?  That is an approach I have been thinking
> of more and more as of late.
>
> At 08:35 PM 7/6/2004, you wrote:
>> I used hidden select lists to restore user selections since I
>> wasn't "allowed" to place the whole form in session scope. The
>> management/maintenance of user selections was indeed ugly (but
>> its done and works fine). My question has to do with the data
>> retrieved from the db (from which the user makes selections). For
>> example, when the form is initially displayed, I populate a list
>> of vehicle lines (i.e. Focus, Mustang, Freestar, and so on). The
>> user can copy a vehicle line from the source list to the target
>> list. The target list consists of user selections. When the page
>> needs to be re-displayed as a result of some other query, I
>> needed to re-populate the list of vehicle lines (the source
>> list). I felt that re-retrieving the same vehicle lines from the
>> db again was silly (since I got it once I simply put a map in
>> session and use it when needed). When posting the form, the list
>> of label value beans is no longer available in the action, so my
>> options were: (1) either store in hidden lists (concatenating the
>> key with the description) or (2) re-retrieve the vehicle lines
>> from the db or (3) place them in session the first they are
>> retrieved and get them from session scope. I chose the third and
>> wondered about some best practices others have used in similar
>> situations. ----- Original Message ----- From: Rick Reumann To:
>> Struts Users Mailing List Sent: Tuesday, July 06, 2004 10:58 PM
>> Subject: Re: some best practices questions
>>
>>
>> Christina Siena wrote:
>>
>>
>>> I recently developed an application with a complex UI. One of
>>> the pages required querying the database based on user
>>> selection and re-displaying the page with the retrieved data
>>> and any previous existing user selections. Four different
>>> fields can trigger a db query resulting in page re-display and
>>> validations can also result in page re-display. Each time the
>>> page is re-displayed, the "state" of the page must be
>>> "remembered" from the last time it was displayed. (still with
>>> me so far?) Most of the data retrieved is list data displayed
>>> in single- or multi-select lists and populated using
>>> html:options collection and LabelValueBean. (for those of you
>>> reading this post who have developed similar code, you will
>>> know what I'm referring to).
>>>
>>> In the action, the retrieved data is placed in session scope to
>>> minimize db hits. I thought this was a good idea at the time.
>>> For some reason, placing data in session scope is frowned upon
>>> by some members of my team (even if improves performance).
>>> Anyways, what I need are some ideas of the best practices that
>>> fellow Struts users follow when a page requires querying the db
>>> and re-displaying the page with the retrieved data and previous
>>> selections if placing the data in session scope is not an
>>> option. How can I recall the previously retrieved data without
>>> requerying the db? Would it make sense to hide the data in the
>>> page? (i.e. either using hidden fields or hidden select lists
>>> or to generate a JavaScript array). What are the risks, if any,
>>> of hiding the data in the page? (i.e. performance).
>>>
>>> If anyone has developed similar pages, can you tell me if you
>>> decided for or against placing data in session scope and why?
>>>
>>
>> Here's is my 2cents. Personally I'm not as anti-session as most
>> people, and I think to use it or not use has to be taken on a
>> case per case basis. If your queries to generate the lists are
>> not going be cached in anyway by the backend and/or they are
>> expensive queries to run, the Session can be a better place to
>> temporarilly store this information as the user progresses
>> through the 'flow' as you've described above. Sure the data each
>> time might not be perfectly fresh, so if that is a requirement
>> than you will need to query after each new selection is chosen.
>> I'd opt for testing out performance making a new query each time
>> to generate your lists for the drop downs and see how it behaves.
>> (If your data in the database will never be altered by an
>> external process you can really leverage something like iBATIS
>> that will cache queries for you so everything is golden).
>>
>> You are asking a two part question, though, and one thing I think
>> that you 'might' be confusing is the use of the lists in Session
>> versus the ActionForm in Session (retaining user's selections).
>> From what you are describing I would DEFIINITELY keep your form
>> bean in Session scope for this. This way any chosen parameters
>> will be remembered as you are brought back to the page. This is a
>> perfectly legit use of the Session and don't let anyone convince
>> you in to using a bunch of hidden variables and storing your form
>> bean in request scope each time. (To me that is so stupid, how
>> much memory is a Form bean going to take up in Session scope
>> weighed out agains the ugliness and maintenance of dealing with a
>> bunch of hidden variables and making sure they are always set
>> etc. USE the Session in this case for you form bean). You are
>> basically describing in a sense a "wizard" where the user might
>> be brought along to different pages to collect data in a form,
>> only you are simply reusing the same form with different lists.
>>
>> --
>> Rick
>>
>>
>> ------------------------------------------------------------------
>> --- To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>> For additional commands, e-mail: user-help@struts.apache.org
>
>
> --------------------------------------------------------------------
> - To unsubscribe, e-mail: user-unsubscribe@struts.apache.org For
> additional commands, e-mail: user-help@struts.apache.org



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


Re: some best practices questions

Posted by Christina Siena <cs...@mountaincable.net>.
I have an idea how to persist the data that I currently place in session scope but I need to run it by someone.

Recall when I said that placing data in session scope is frowned upon by some members of my team? Well no one said anything about not using Java serialization. Why couldn't I serialize the 
same data that I currently keep in session scope? I've already implemented a solution for streaming images so creating a temp file should not be a problem. Here is what I think I will need:

In the action where the data is first retrieved:

  try {
   final String prefix = "myVehicleLineMap";
   final String suffix = null;
   File file = File.createTempFile(prefix, suffix);
   FileOutputStream fileOutputStream = new FileOutputStream(file);
   ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
   objectOutputStream.writeObject(myMap);
   objectOutputStream.flush();
   myForm.setTempFileName(file.getAbsolutePath());
  } catch (Exception e) {
   System.out.println(this.getClass().getName() + "==>> " + e.toString());
  }

In the action where the data needs to be re-accessed to prepare the page for re-display:

  try {

   FileInputStream fileInputStream = new FileInputStream(myForm.getTempFileName()); 
   ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); 
   SortedMap myMap = (SortedMap) objectInputStream.readObject(); 
   // use myMap as before (when in session scope)
  } catch (Exception e) {
   System.out.println(this.getClass().getName() + "==>> " + e.toString());
  }

This is just an idea at this point, so I would welcome any feedback. I'm not sure if this will work or if its feasible, but at least it may generate some more ideas.

  ----- Original Message ----- 
  From: Michael McGrady 
  To: Struts Users Mailing List 
  Sent: Tuesday, July 06, 2004 11:59 PM
  Subject: Re: some best practices questions


  Ever thought about creating a new scope managed by your own manager from 
  application scope?  That is an approach I have been thinking of more and 
  more as of late.

  At 08:35 PM 7/6/2004, you wrote:
  >I used hidden select lists to restore user selections since I wasn't 
  >"allowed" to place the whole form in session scope. The 
  >management/maintenance of user selections was indeed ugly (but its done 
  >and works fine). My question has to do with the data retrieved from the db 
  >(from which the user makes selections). For example, when the form is 
  >initially displayed, I populate a list of vehicle lines (i.e. Focus, 
  >Mustang, Freestar, and so on). The user can copy a vehicle line from the 
  >source list to the target list. The target list consists of user 
  >selections. When the page needs to be re-displayed as a result of some 
  >other query, I needed to re-populate the list of vehicle lines (the source 
  >list). I felt that re-retrieving the same vehicle lines from the db again 
  >was silly (since I got it once I simply put a map in session and use it 
  >when needed). When posting the form, the list of label value beans is no 
  >longer available in the action, so my options were: (1) either store in 
  >hidden lists (concatenating the key with the description) or (2) 
  >re-retrieve the vehicle lines from the db or (3) place them in session the 
  >first they are retrieved and get them from session scope. I chose the 
  >third and wondered about some best practices others have used in similar 
  >situations.
  >   ----- Original Message -----
  >   From: Rick Reumann
  >   To: Struts Users Mailing List
  >   Sent: Tuesday, July 06, 2004 10:58 PM
  >   Subject: Re: some best practices questions
  >
  >
  >   Christina Siena wrote:
  >
  >   > I recently developed an application with a complex UI. One of the
  >   > pages required querying the database based on user selection and
  >   > re-displaying the page with the retrieved data and any previous
  >   > existing user selections. Four different fields can trigger a db
  >   > query resulting in page re-display and validations can also result in
  >   > page re-display. Each time the page is re-displayed, the "state" of
  >   > the page must be "remembered" from the last time it was displayed.
  >   > (still with me so far?) Most of the data retrieved is list data
  >   > displayed in single- or multi-select lists and populated using
  >   > html:options collection and LabelValueBean. (for those of you reading
  >   > this post who have developed similar code, you will know what I'm
  >   > referring to).
  >   >
  >   > In the action, the retrieved data is placed in session scope to
  >   > minimize db hits. I thought this was a good idea at the time. For
  >   > some reason, placing data in session scope is frowned upon by some
  >   > members of my team (even if improves performance). Anyways, what I
  >   > need are some ideas of the best practices that fellow Struts users
  >   > follow when a page requires querying the db and re-displaying the
  >   > page with the retrieved data and previous selections if placing the
  >   > data in session scope is not an option. How can I recall the
  >   > previously retrieved data without requerying the db? Would it make
  >   > sense to hide the data in the page? (i.e. either using hidden fields
  >   > or hidden select lists or to generate a JavaScript array). What are
  >   > the risks, if any, of hiding the data in the page? (i.e.
  >   > performance).
  >   >
  >   > If anyone has developed similar pages, can you tell me if you decided
  >   > for or against placing data in session scope and why?
  >
  >   Here's is my 2cents. Personally I'm not as anti-session as most people,
  >   and I think to use it or not use has to be taken on a case per case
  >   basis. If your queries to generate the lists are not going be cached in
  >   anyway by the backend and/or they are expensive queries to run, the
  >   Session can be a better place to temporarilly store this information as
  >   the user progresses through the 'flow' as you've described above. Sure
  >   the data each time might not be perfectly fresh, so if that is a
  >   requirement than you will need to query after each new selection is
  >   chosen. I'd opt for testing out performance making a new query each time
  >   to generate your lists for the drop downs and see how it behaves. (If
  >   your data in the database will never be altered by an external process
  >   you can really leverage something like iBATIS that will cache queries
  >   for you so everything is golden).
  >
  >   You are asking a two part question, though, and one thing I think that
  >   you 'might' be confusing is the use of the lists in Session versus the
  >   ActionForm in Session (retaining user's selections). From what you are
  >   describing I would DEFIINITELY keep your form bean in Session scope for
  >   this. This way any chosen parameters will be remembered as you are
  >   brought back to the page. This is a perfectly legit use of the Session
  >   and don't let anyone convince you in to using a bunch of hidden
  >   variables and storing your form bean in request scope each time. (To me
  >   that is so stupid, how much memory is a Form bean going to take up in
  >   Session scope weighed out agains the ugliness and maintenance of dealing
  >   with a bunch of hidden variables and making sure they are always set
  >   etc. USE the Session in this case for you form bean). You are basically
  >   describing in a sense a "wizard" where the user might be brought along
  >   to different pages to collect data in a form, only you are simply
  >   reusing the same form with different lists.
  >
  >   --
  >   Rick
  >
  >   ---------------------------------------------------------------------
  >   To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
  >   For additional commands, e-mail: user-help@struts.apache.org



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


Re: some best practices questions

Posted by Christina Siena <cs...@mountaincable.net>.
Your idea about creating a new scope sounds like an idea that might help. Can you tell me more about it?
  ----- Original Message ----- 
  From: Michael McGrady 
  To: Struts Users Mailing List 
  Sent: Tuesday, July 06, 2004 11:59 PM
  Subject: Re: some best practices questions


  Ever thought about creating a new scope managed by your own manager from 
  application scope?  That is an approach I have been thinking of more and 
  more as of late.

  At 08:35 PM 7/6/2004, you wrote:
  >I used hidden select lists to restore user selections since I wasn't 
  >"allowed" to place the whole form in session scope. The 
  >management/maintenance of user selections was indeed ugly (but its done 
  >and works fine). My question has to do with the data retrieved from the db 
  >(from which the user makes selections). For example, when the form is 
  >initially displayed, I populate a list of vehicle lines (i.e. Focus, 
  >Mustang, Freestar, and so on). The user can copy a vehicle line from the 
  >source list to the target list. The target list consists of user 
  >selections. When the page needs to be re-displayed as a result of some 
  >other query, I needed to re-populate the list of vehicle lines (the source 
  >list). I felt that re-retrieving the same vehicle lines from the db again 
  >was silly (since I got it once I simply put a map in session and use it 
  >when needed). When posting the form, the list of label value beans is no 
  >longer available in the action, so my options were: (1) either store in 
  >hidden lists (concatenating the key with the description) or (2) 
  >re-retrieve the vehicle lines from the db or (3) place them in session the 
  >first they are retrieved and get them from session scope. I chose the 
  >third and wondered about some best practices others have used in similar 
  >situations.
  >   ----- Original Message -----
  >   From: Rick Reumann
  >   To: Struts Users Mailing List
  >   Sent: Tuesday, July 06, 2004 10:58 PM
  >   Subject: Re: some best practices questions
  >
  >
  >   Christina Siena wrote:
  >
  >   > I recently developed an application with a complex UI. One of the
  >   > pages required querying the database based on user selection and
  >   > re-displaying the page with the retrieved data and any previous
  >   > existing user selections. Four different fields can trigger a db
  >   > query resulting in page re-display and validations can also result in
  >   > page re-display. Each time the page is re-displayed, the "state" of
  >   > the page must be "remembered" from the last time it was displayed.
  >   > (still with me so far?) Most of the data retrieved is list data
  >   > displayed in single- or multi-select lists and populated using
  >   > html:options collection and LabelValueBean. (for those of you reading
  >   > this post who have developed similar code, you will know what I'm
  >   > referring to).
  >   >
  >   > In the action, the retrieved data is placed in session scope to
  >   > minimize db hits. I thought this was a good idea at the time. For
  >   > some reason, placing data in session scope is frowned upon by some
  >   > members of my team (even if improves performance). Anyways, what I
  >   > need are some ideas of the best practices that fellow Struts users
  >   > follow when a page requires querying the db and re-displaying the
  >   > page with the retrieved data and previous selections if placing the
  >   > data in session scope is not an option. How can I recall the
  >   > previously retrieved data without requerying the db? Would it make
  >   > sense to hide the data in the page? (i.e. either using hidden fields
  >   > or hidden select lists or to generate a JavaScript array). What are
  >   > the risks, if any, of hiding the data in the page? (i.e.
  >   > performance).
  >   >
  >   > If anyone has developed similar pages, can you tell me if you decided
  >   > for or against placing data in session scope and why?
  >
  >   Here's is my 2cents. Personally I'm not as anti-session as most people,
  >   and I think to use it or not use has to be taken on a case per case
  >   basis. If your queries to generate the lists are not going be cached in
  >   anyway by the backend and/or they are expensive queries to run, the
  >   Session can be a better place to temporarilly store this information as
  >   the user progresses through the 'flow' as you've described above. Sure
  >   the data each time might not be perfectly fresh, so if that is a
  >   requirement than you will need to query after each new selection is
  >   chosen. I'd opt for testing out performance making a new query each time
  >   to generate your lists for the drop downs and see how it behaves. (If
  >   your data in the database will never be altered by an external process
  >   you can really leverage something like iBATIS that will cache queries
  >   for you so everything is golden).
  >
  >   You are asking a two part question, though, and one thing I think that
  >   you 'might' be confusing is the use of the lists in Session versus the
  >   ActionForm in Session (retaining user's selections). From what you are
  >   describing I would DEFIINITELY keep your form bean in Session scope for
  >   this. This way any chosen parameters will be remembered as you are
  >   brought back to the page. This is a perfectly legit use of the Session
  >   and don't let anyone convince you in to using a bunch of hidden
  >   variables and storing your form bean in request scope each time. (To me
  >   that is so stupid, how much memory is a Form bean going to take up in
  >   Session scope weighed out agains the ugliness and maintenance of dealing
  >   with a bunch of hidden variables and making sure they are always set
  >   etc. USE the Session in this case for you form bean). You are basically
  >   describing in a sense a "wizard" where the user might be brought along
  >   to different pages to collect data in a form, only you are simply
  >   reusing the same form with different lists.
  >
  >   --
  >   Rick
  >
  >   ---------------------------------------------------------------------
  >   To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
  >   For additional commands, e-mail: user-help@struts.apache.org



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


Re: some best practices questions

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Ever thought about creating a new scope managed by your own manager from 
application scope?  That is an approach I have been thinking of more and 
more as of late.

At 08:35 PM 7/6/2004, you wrote:
>I used hidden select lists to restore user selections since I wasn't 
>"allowed" to place the whole form in session scope. The 
>management/maintenance of user selections was indeed ugly (but its done 
>and works fine). My question has to do with the data retrieved from the db 
>(from which the user makes selections). For example, when the form is 
>initially displayed, I populate a list of vehicle lines (i.e. Focus, 
>Mustang, Freestar, and so on). The user can copy a vehicle line from the 
>source list to the target list. The target list consists of user 
>selections. When the page needs to be re-displayed as a result of some 
>other query, I needed to re-populate the list of vehicle lines (the source 
>list). I felt that re-retrieving the same vehicle lines from the db again 
>was silly (since I got it once I simply put a map in session and use it 
>when needed). When posting the form, the list of label value beans is no 
>longer available in the action, so my options were: (1) either store in 
>hidden lists (concatenating the key with the description) or (2) 
>re-retrieve the vehicle lines from the db or (3) place them in session the 
>first they are retrieved and get them from session scope. I chose the 
>third and wondered about some best practices others have used in similar 
>situations.
>   ----- Original Message -----
>   From: Rick Reumann
>   To: Struts Users Mailing List
>   Sent: Tuesday, July 06, 2004 10:58 PM
>   Subject: Re: some best practices questions
>
>
>   Christina Siena wrote:
>
>   > I recently developed an application with a complex UI. One of the
>   > pages required querying the database based on user selection and
>   > re-displaying the page with the retrieved data and any previous
>   > existing user selections. Four different fields can trigger a db
>   > query resulting in page re-display and validations can also result in
>   > page re-display. Each time the page is re-displayed, the "state" of
>   > the page must be "remembered" from the last time it was displayed.
>   > (still with me so far?) Most of the data retrieved is list data
>   > displayed in single- or multi-select lists and populated using
>   > html:options collection and LabelValueBean. (for those of you reading
>   > this post who have developed similar code, you will know what I'm
>   > referring to).
>   >
>   > In the action, the retrieved data is placed in session scope to
>   > minimize db hits. I thought this was a good idea at the time. For
>   > some reason, placing data in session scope is frowned upon by some
>   > members of my team (even if improves performance). Anyways, what I
>   > need are some ideas of the best practices that fellow Struts users
>   > follow when a page requires querying the db and re-displaying the
>   > page with the retrieved data and previous selections if placing the
>   > data in session scope is not an option. How can I recall the
>   > previously retrieved data without requerying the db? Would it make
>   > sense to hide the data in the page? (i.e. either using hidden fields
>   > or hidden select lists or to generate a JavaScript array). What are
>   > the risks, if any, of hiding the data in the page? (i.e.
>   > performance).
>   >
>   > If anyone has developed similar pages, can you tell me if you decided
>   > for or against placing data in session scope and why?
>
>   Here's is my 2cents. Personally I'm not as anti-session as most people,
>   and I think to use it or not use has to be taken on a case per case
>   basis. If your queries to generate the lists are not going be cached in
>   anyway by the backend and/or they are expensive queries to run, the
>   Session can be a better place to temporarilly store this information as
>   the user progresses through the 'flow' as you've described above. Sure
>   the data each time might not be perfectly fresh, so if that is a
>   requirement than you will need to query after each new selection is
>   chosen. I'd opt for testing out performance making a new query each time
>   to generate your lists for the drop downs and see how it behaves. (If
>   your data in the database will never be altered by an external process
>   you can really leverage something like iBATIS that will cache queries
>   for you so everything is golden).
>
>   You are asking a two part question, though, and one thing I think that
>   you 'might' be confusing is the use of the lists in Session versus the
>   ActionForm in Session (retaining user's selections). From what you are
>   describing I would DEFIINITELY keep your form bean in Session scope for
>   this. This way any chosen parameters will be remembered as you are
>   brought back to the page. This is a perfectly legit use of the Session
>   and don't let anyone convince you in to using a bunch of hidden
>   variables and storing your form bean in request scope each time. (To me
>   that is so stupid, how much memory is a Form bean going to take up in
>   Session scope weighed out agains the ugliness and maintenance of dealing
>   with a bunch of hidden variables and making sure they are always set
>   etc. USE the Session in this case for you form bean). You are basically
>   describing in a sense a "wizard" where the user might be brought along
>   to different pages to collect data in a form, only you are simply
>   reusing the same form with different lists.
>
>   --
>   Rick
>
>   ---------------------------------------------------------------------
>   To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>   For additional commands, e-mail: user-help@struts.apache.org



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


Re: some best practices questions

Posted by Christina Siena <cs...@mountaincable.net>.
I used hidden select lists to restore user selections since I wasn't "allowed" to place the whole form in session scope. The management/maintenance of user selections was indeed ugly (but its done and works fine). My question has to do with the data retrieved from the db (from which the user makes selections). For example, when the form is initially displayed, I populate a list of vehicle lines (i.e. Focus, Mustang, Freestar, and so on). The user can copy a vehicle line from the source list to the target list. The target list consists of user selections. When the page needs to be re-displayed as a result of some other query, I needed to re-populate the list of vehicle lines (the source list). I felt that re-retrieving the same vehicle lines from the db again was silly (since I got it once I simply put a map in session and use it when needed). When posting the form, the list of label value beans is no longer available in the action, so my options were: (1) either store in hidden lists (concatenating the key with the description) or (2) re-retrieve the vehicle lines from the db or (3) place them in session the first they are retrieved and get them from session scope. I chose the third and wondered about some best practices others have used in similar situations.
  ----- Original Message ----- 
  From: Rick Reumann 
  To: Struts Users Mailing List 
  Sent: Tuesday, July 06, 2004 10:58 PM
  Subject: Re: some best practices questions


  Christina Siena wrote:

  > I recently developed an application with a complex UI. One of the
  > pages required querying the database based on user selection and
  > re-displaying the page with the retrieved data and any previous
  > existing user selections. Four different fields can trigger a db
  > query resulting in page re-display and validations can also result in
  > page re-display. Each time the page is re-displayed, the "state" of
  > the page must be "remembered" from the last time it was displayed.
  > (still with me so far?) Most of the data retrieved is list data
  > displayed in single- or multi-select lists and populated using
  > html:options collection and LabelValueBean. (for those of you reading
  > this post who have developed similar code, you will know what I'm
  > referring to).
  > 
  > In the action, the retrieved data is placed in session scope to
  > minimize db hits. I thought this was a good idea at the time. For
  > some reason, placing data in session scope is frowned upon by some
  > members of my team (even if improves performance). Anyways, what I
  > need are some ideas of the best practices that fellow Struts users
  > follow when a page requires querying the db and re-displaying the
  > page with the retrieved data and previous selections if placing the
  > data in session scope is not an option. How can I recall the
  > previously retrieved data without requerying the db? Would it make
  > sense to hide the data in the page? (i.e. either using hidden fields
  > or hidden select lists or to generate a JavaScript array). What are
  > the risks, if any, of hiding the data in the page? (i.e.
  > performance).
  > 
  > If anyone has developed similar pages, can you tell me if you decided
  > for or against placing data in session scope and why?

  Here's is my 2cents. Personally I'm not as anti-session as most people, 
  and I think to use it or not use has to be taken on a case per case 
  basis. If your queries to generate the lists are not going be cached in 
  anyway by the backend and/or they are expensive queries to run, the 
  Session can be a better place to temporarilly store this information as 
  the user progresses through the 'flow' as you've described above. Sure 
  the data each time might not be perfectly fresh, so if that is a 
  requirement than you will need to query after each new selection is 
  chosen. I'd opt for testing out performance making a new query each time 
  to generate your lists for the drop downs and see how it behaves. (If 
  your data in the database will never be altered by an external process 
  you can really leverage something like iBATIS that will cache queries 
  for you so everything is golden).

  You are asking a two part question, though, and one thing I think that 
  you 'might' be confusing is the use of the lists in Session versus the 
  ActionForm in Session (retaining user's selections). From what you are 
  describing I would DEFIINITELY keep your form bean in Session scope for 
  this. This way any chosen parameters will be remembered as you are 
  brought back to the page. This is a perfectly legit use of the Session 
  and don't let anyone convince you in to using a bunch of hidden 
  variables and storing your form bean in request scope each time. (To me 
  that is so stupid, how much memory is a Form bean going to take up in 
  Session scope weighed out agains the ugliness and maintenance of dealing 
  with a bunch of hidden variables and making sure they are always set 
  etc. USE the Session in this case for you form bean). You are basically 
  describing in a sense a "wizard" where the user might be brought along 
  to different pages to collect data in a form, only you are simply 
  reusing the same form with different lists.

  -- 
  Rick

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


Re: some best practices questions

Posted by Rick Reumann <st...@reumann.net>.
Christina Siena wrote:

> I recently developed an application with a complex UI. One of the
> pages required querying the database based on user selection and
> re-displaying the page with the retrieved data and any previous
> existing user selections. Four different fields can trigger a db
> query resulting in page re-display and validations can also result in
> page re-display. Each time the page is re-displayed, the "state" of
> the page must be "remembered" from the last time it was displayed.
> (still with me so far?) Most of the data retrieved is list data
> displayed in single- or multi-select lists and populated using
> html:options collection and LabelValueBean. (for those of you reading
> this post who have developed similar code, you will know what I'm
> referring to).
> 
> In the action, the retrieved data is placed in session scope to
> minimize db hits. I thought this was a good idea at the time. For
> some reason, placing data in session scope is frowned upon by some
> members of my team (even if improves performance). Anyways, what I
> need are some ideas of the best practices that fellow Struts users
> follow when a page requires querying the db and re-displaying the
> page with the retrieved data and previous selections if placing the
> data in session scope is not an option. How can I recall the
> previously retrieved data without requerying the db? Would it make
> sense to hide the data in the page? (i.e. either using hidden fields
> or hidden select lists or to generate a JavaScript array). What are
> the risks, if any, of hiding the data in the page? (i.e.
> performance).
> 
> If anyone has developed similar pages, can you tell me if you decided
> for or against placing data in session scope and why?

Here's is my 2cents. Personally I'm not as anti-session as most people, 
and I think to use it or not use has to be taken on a case per case 
basis. If your queries to generate the lists are not going be cached in 
anyway by the backend and/or they are expensive queries to run, the 
Session can be a better place to temporarilly store this information as 
the user progresses through the 'flow' as you've described above. Sure 
the data each time might not be perfectly fresh, so if that is a 
requirement than you will need to query after each new selection is 
chosen. I'd opt for testing out performance making a new query each time 
to generate your lists for the drop downs and see how it behaves. (If 
your data in the database will never be altered by an external process 
you can really leverage something like iBATIS that will cache queries 
for you so everything is golden).

You are asking a two part question, though, and one thing I think that 
you 'might' be confusing is the use of the lists in Session versus the 
ActionForm in Session (retaining user's selections). From what you are 
describing I would DEFIINITELY keep your form bean in Session scope for 
this. This way any chosen parameters will be remembered as you are 
brought back to the page. This is a perfectly legit use of the Session 
and don't let anyone convince you in to using a bunch of hidden 
variables and storing your form bean in request scope each time. (To me 
that is so stupid, how much memory is a Form bean going to take up in 
Session scope weighed out agains the ugliness and maintenance of dealing 
with a bunch of hidden variables and making sure they are always set 
etc. USE the Session in this case for you form bean). You are basically 
describing in a sense a "wizard" where the user might be brought along 
to different pages to collect data in a form, only you are simply 
reusing the same form with different lists.

-- 
Rick

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


Re: some best practices questions

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
Thanks for the heads up, Rick.  I think this whole area just needs a 
concerted and orchestrated look.  The standard approaches just are not 
working for people.  This is really so recurrent is more than recurrent.

At 09:59 PM 7/6/2004, you wrote:
>On Tue, 06 Jul 2004 20:58:16 -0700, Michael McGrady
><mi...@michaelmcgrady.com> wrote:
>
>>I wouldn't mind an ongoing discussion group on this alone somehow, if
>>there were a way to do that.  I might create a forum for that.
>
>I created a model-struts group on yahoo groups for discussing more of the
>model layer components as they relate to struts. However, this list is
>rarely used. (Robert Taylor and myself are the only ones who answer the
>occoassional questions there:) I suggest just bringing up any of the
>discussion here on this list. Makes it nice for when you want to get info
>back from the archives. Plus nice to hear about practical solutions people
>have to solving common issues.
>
>--
>Rick
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>For additional commands, e-mail: user-help@struts.apache.org
>
>



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


Re: some best practices questions

Posted by Rick Reumann <st...@reumann.net>.
On Tue, 06 Jul 2004 20:58:16 -0700, Michael McGrady  
<mi...@michaelmcgrady.com> wrote:

> I wouldn't mind an ongoing discussion group on this alone somehow, if  
> there were a way to do that.  I might create a forum for that.

I created a model-struts group on yahoo groups for discussing more of the  
model layer components as they relate to struts. However, this list is  
rarely used. (Robert Taylor and myself are the only ones who answer the  
occoassional questions there:) I suggest just bringing up any of the  
discussion here on this list. Makes it nice for when you want to get info  
back from the archives. Plus nice to hear about practical solutions people  
have to solving common issues.

-- 
Rick

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


Re: some best practices questions

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
I think the obvious is important with this recurrent problem.  The obvious 
is that you want to persist data for a period that is not coincident with 
the normal devices for doing that. i.e. request, session and context 
scopes.  The difficulty is matching up with storage method on the server 
with the "life-term" of the client.  There are any number of solutions to 
this problem with varying pluses and minuses, and I think you really have 
to solve what you need for your problem.  I have no doubt that there are 
recurrent problems and that some general solutions to those particular 
recurrent problems would be useful.  I have been mulling this around in my 
head for a while trying to get some sense about this.  I wouldn't mind an 
ongoing discussion group on this alone somehow, if there were a way to do 
that.  I might create a forum for that.



At 07:43 PM 7/6/2004, you wrote:
>I recently developed an application with a complex UI. One of the pages 
>required querying the database based on user selection and re-displaying 
>the page with the retrieved data and any previous existing user 
>selections. Four different fields can trigger a db query resulting in page 
>re-display and validations can also result in page re-display. Each time 
>the page is re-displayed, the "state" of the page must be "remembered" 
>from the last time it was displayed. (still with me so far?) Most of the 
>data retrieved is list data displayed in single- or multi-select lists and 
>populated using html:options collection and LabelValueBean. (for those of 
>you reading this post who have developed similar code, you will know what 
>I'm referring to).
>
>In the action, the retrieved data is placed in session scope to minimize 
>db hits. I thought this was a good idea at the time. For some reason, 
>placing data in session scope is frowned upon by some members of my team 
>(even if improves performance). Anyways, what I need are some ideas of the 
>best practices that fellow Struts users follow when a page requires 
>querying the db and re-displaying the page with the retrieved data and 
>previous selections if placing the data in session scope is not an option. 
>How can I recall the previously retrieved data without requerying the db? 
>Would it make sense to hide the data in the page? (i.e. either using 
>hidden fields or hidden select lists or to generate a JavaScript array). 
>What are the risks, if any, of hiding the data in the page? (i.e. performance).
>
>If anyone has developed similar pages, can you tell me if you decided for 
>or against placing data in session scope and why?
>
>Any ideas would be appreciated.
>
>Thanks in advance.



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


Re: some best practices questions

Posted by Rick Reumann <st...@reumann.net>.
On Wed, 07 Jul 2004 13:57:23 +0200, Bryan Hunt <ad...@revoltingdigits.com>  
wrote:

> For instance if I want to page through it ( using displaytags.org (10  
> out of 10)) or simply if I don't want to fetch
> from the database time and time again.
> By default the data expires on an hourly basis. And if a different  
> combination of parameters is sent it expires
> the cached stuff.

Nice code, but if you use iBATIS http://www.ibatis.com for your  
persistence layer you get all of that functionality out of the box. Takes  
care of all the caching for you. It'll even always flush the cache  
whenever an update or insert is peformed. So basically you make the same  
simple DAO call... ie. myDao.getMyList().. and you don't have to worry  
about it whether you need a fresh query or not.

Unfortunately as cool as caching is, in many(most?) situations the  
database is not just modified by your application, so you can't rely on  
the cache being flushed at appropriate times. For example say the  
inventory to display is updated in the database by some other process  
outside of your web application. When displaying the inventory you always  
want to make sure you have the most recent inventory so you can't rely on  
caching.

-- 
Rick

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


Re: some best practices questions

Posted by bryan <ni...@gmail.com>.
I myself get caching with hibernate which I am using for persistance 
but I wanted the more fine grained control like this so that I could page 
back and forth using displaytag.org. 

here is my jsp code for paging, hope this shows why I am doing it. I guess 
my code is more for implimenting a client view than for heavy duty caching.

snip=
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/c" prefix="c" %>
<%@ taglib uri="/tags/displaytag-el-12" prefix="display" %>

<c:set var="forSaleProperties" value="${forSaleProperties}"></c:set>
<c:set var="contextPath" value="${request.getContextPath}"></c:set>
<c:out value="${request.getContextPath}"/>

<display:table name="${forSaleProperties}" pagesize="15"
requestURI="${pageContext.request.contextPath}/client-search-for-sale-properties-action.do">
	<display:column property="id" title="Id"
href="${pageContext.request.contextPath}/client-property-view-for-sale-action.do"
paramId="id"  paramProperty="id"/>
	<display:column property="name" title="Name"/>
	<display:column property="shortDescription" title="Desc"/>
	<display:column property="town" title="Town" sortable="true"/>
	<display:setProperty name="sort.behavior" value="list" />
	<display:setProperty name="paging.banner.include_first_last" value="true" />
</display:table>
=snip

Cause everything is cached it is a snip to move back and forth through
the records.

--b


On Wed, 07 Jul 2004 08:41:39 -0700, Michael McGrady
<mi...@michaelmcgrady.com> wrote:
> I, for one and one only, think that this sort of thing is directly
> addressing the most common recurrent question on this list.  So, if
> anything, this de-spams the list.  Thanks for the suggestion.
> 
> At 04:57 AM 7/7/2004, you wrote:
> >Sorry if this is considered spamming the list ....
> >
> >Speaking of storing stuff in session scope. I've developed what I think is
> >a handy class which I think it useful for
> >when I want to store something like a search in a session variable.
> >
> >For instance if I want to page through it ( using displaytags.org (10 out
> >of 10)) or simply if I don't want to fetch
> >from the database time and time again.
> >By default the data expires on an hourly basis. And if a different
> >combination of parameters is sent it expires
> >the cached stuff.
> >
> >Here is the class
> >
> >snip=
> >package ie.jestate.struts.client;
> >
> >import java.util.Date;
> >
> >/**
> >* @author Bryan Hunt
> >*/
> >//TODO:Perhaps I should be generating a MD5 or something but I can't see a
> >good reason to use any more CPU
> >
> >public class HashGenerator {
> >
> >    private StringBuffer buffer;
> >
> >
> >    /**
> >     *
> >     */
> >    public HashGenerator() {
> >        super();
> >        buffer = new StringBuffer(50);
> >        // TODO Auto-generated constructor stub
> >    }
> >
> >    /**
> >     * @param urbanAreas
> >     */
> >    public void add(Integer[] array,String fieldname) {
> >        for (int i = 0; i < array.length; i++) {
> >            Integer integer = array[i];
> >            buffer.append(integer);
> >        }
> >        buffer.append(fieldname);
> >        buffer.append("-");
> >    }
> >
> >    /**
> >     * @param priceRangeStart
> >     */
> >    public void add(Integer integer,String fieldname) {
> >        // TODO Auto-generated method stub
> >        buffer.append(integer);
> >        buffer.append(fieldname);
> >        buffer.append("-");
> >    }
> >
> >    /**
> >     * @return
> >     */
> >    public String getHash() {
> >
> >        //I append the hour onto the end of the string so that a hash will
> >        //only be good for a max of one hour.
> >        Date date = new Date();
> >
> >        return buffer.toString()+ "-" + new Integer(date.getHours());
> >    }
> >
> >}
> >
> >=snip
> >
> >And here is example usage.
> >snip=
> >/*
> >* Created on 24-Jun-2004
> >*/
> >package ie.jestate.struts.client;
> >
> >import ie.jestate.struts.BaseAction;
> >
> >import java.util.Set;
> >
> >import javax.servlet.http.HttpServletRequest;
> >import javax.servlet.http.HttpServletResponse;
> >import javax.servlet.http.HttpSession;
> >
> >import org.apache.struts.action.ActionForm;
> >import org.apache.struts.action.ActionForward;
> >import org.apache.struts.action.ActionMapping;
> >import org.apache.struts.action.DynaActionForm;
> >
> >/**
> >* @author Bryan Hunt
> >  *
> >*/
> >public class ForSaleSearchAction extends BaseAction {
> >
> >    /* (non-Javadoc)
> >     * @see
> > org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping,
> > org.apache.struts.action.ActionForm,
> > javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
> >     */
> >    public ActionForward execute(
> >        ActionMapping actionMapping,
> >        ActionForm actionForm,
> >        HttpServletRequest request,
> >        HttpServletResponse response)
> >        throws Exception {
> >
> >        //TODO: Database based initialization of the countries collection
> >        DynaActionForm dynaform = (DynaActionForm) actionForm;
> >        HttpSession session = request.getSession();
> >        String forSalePropertiesSearchCheckSum = (String)
> > session.getAttribute(Constants.FOR_SALE_CHECK_SUM);
> >        String newForSalePropertiesSearchCheckSum = null;
> >
> >        Integer[] urbanAreas = (Integer[]) dynaform.get("urbanAreas");
> >        Integer priceRangeStart = (Integer) dynaform.get("priceRangeStart");
> >        Integer priceRangeEnd = (Integer) dynaform.get("priceRangeEnd");
> >        Integer[] propertyTypes = (Integer[]) dynaform.get("propertyTypes");
> >
> >        HashGenerator hashGenerator = new HashGenerator();
> >                    hashGenerator.add(urbanAreas,"urbanAreas");
> >                    hashGenerator.add(priceRangeStart,"priceRangeStart");
> >                    hashGenerator.add(priceRangeEnd,"priceRangeEnd");
> >                    hashGenerator.add(propertyTypes,"propertyTypes");
> >                    newForSalePropertiesSearchCheckSum =
> > hashGenerator.getHash();
> >
> >            if(forSalePropertiesSearchCheckSum != null &&
> > forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)) {
> >                System.out.println("Checksums match");
> >            }
> >
> >        if (forSalePropertiesSearchCheckSum == null
> >            ||
> > !forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)){
> >
> >            Set forSaleProperties =
> >                findForSaleProperties(
> >                    urbanAreas,
> >                    priceRangeStart,
> >                    priceRangeEnd,
> >                    propertyTypes);
> >
> >session.setAttribute(Constants.FOR_SALE_PROPERTIES_SEARCH_RESULT,
> >forSaleProperties);
> >            session.setAttribute(
> >                Constants.FOR_SALE_CHECK_SUM,
> >                newForSalePropertiesSearchCheckSum);
> >//                TODO:Add logging functionality
> >                System.out.println("Returning fresh search results");
> >
> >        } else
> >        /*
> >                  if (
> >
> >session.getAttribute("forSalePropertiesSearchCheckSum").equals(
> >                        forSalePropertiesSearchCheckSum))
> >                 */
> >            {
> >            //This means that it is the same search, just called again.
> >            //TODO:Add logging functionality
> >            System.out.println("Returning cached search results");
> >
> >
> >        }
> >
> >        //TODO: Decent logging is needed here
> >        System.out.println(forSalePropertiesSearchCheckSum);
> >        System.out.println(newForSalePropertiesSearchCheckSum);
> >        System.out.println(" ---------------------------------------" );
> >
> >        return actionMapping.findForward("success");
> >        }
> >}
> >
> >=snip
> >
> >
> >
> >
> >Christina Siena wrote:
> >
> >>I recently developed an application with a complex UI. One of the pages
> >>required querying the database based on user selection and re-displaying
> >>the page with the retrieved data and any previous existing user
> >>selections. Four different fields can trigger a db query resulting in
> >>page re-display and validations can also result in page re-display. Each
> >>time the page is re-displayed, the "state" of the page must be
> >>"remembered" from the last time it was displayed. (still with me so far?)
> >>Most of the data re
> 
> 
> >>
> >
> >---------------------------------------------------------------------
> >To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> >For additional commands, e-mail: user-help@struts.apache.org
> >
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
>

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


Re: some best practices questions

Posted by Michael McGrady <mi...@michaelmcgrady.com>.
I, for one and one only, think that this sort of thing is directly 
addressing the most common recurrent question on this list.  So, if 
anything, this de-spams the list.  Thanks for the suggestion.

At 04:57 AM 7/7/2004, you wrote:
>Sorry if this is considered spamming the list ....
>
>Speaking of storing stuff in session scope. I've developed what I think is 
>a handy class which I think it useful for
>when I want to store something like a search in a session variable.
>
>For instance if I want to page through it ( using displaytags.org (10 out 
>of 10)) or simply if I don't want to fetch
>from the database time and time again.
>By default the data expires on an hourly basis. And if a different 
>combination of parameters is sent it expires
>the cached stuff.
>
>Here is the class
>
>snip=
>package ie.jestate.struts.client;
>
>import java.util.Date;
>
>/**
>* @author Bryan Hunt
>*/
>//TODO:Perhaps I should be generating a MD5 or something but I can't see a 
>good reason to use any more CPU
>
>public class HashGenerator {
>
>    private StringBuffer buffer;
>
>
>    /**
>     *
>     */
>    public HashGenerator() {
>        super();
>        buffer = new StringBuffer(50);
>        // TODO Auto-generated constructor stub
>    }
>
>    /**
>     * @param urbanAreas
>     */
>    public void add(Integer[] array,String fieldname) {
>        for (int i = 0; i < array.length; i++) {
>            Integer integer = array[i];
>            buffer.append(integer);
>        }
>        buffer.append(fieldname);
>        buffer.append("-");
>    }
>
>    /**
>     * @param priceRangeStart
>     */
>    public void add(Integer integer,String fieldname) {
>        // TODO Auto-generated method stub
>        buffer.append(integer);
>        buffer.append(fieldname);
>        buffer.append("-");
>    }
>
>    /**
>     * @return
>     */
>    public String getHash() {
>
>        //I append the hour onto the end of the string so that a hash will
>        //only be good for a max of one hour.
>        Date date = new Date();
>
>        return buffer.toString()+ "-" + new Integer(date.getHours());
>    }
>
>}
>
>=snip
>
>And here is example usage.
>snip=
>/*
>* Created on 24-Jun-2004
>*/
>package ie.jestate.struts.client;
>
>import ie.jestate.struts.BaseAction;
>
>import java.util.Set;
>
>import javax.servlet.http.HttpServletRequest;
>import javax.servlet.http.HttpServletResponse;
>import javax.servlet.http.HttpSession;
>
>import org.apache.struts.action.ActionForm;
>import org.apache.struts.action.ActionForward;
>import org.apache.struts.action.ActionMapping;
>import org.apache.struts.action.DynaActionForm;
>
>/**
>* @author Bryan Hunt
>  *
>*/
>public class ForSaleSearchAction extends BaseAction {
>
>    /* (non-Javadoc)
>     * @see 
> org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 
> org.apache.struts.action.ActionForm, 
> javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
>     */
>    public ActionForward execute(
>        ActionMapping actionMapping,
>        ActionForm actionForm,
>        HttpServletRequest request,
>        HttpServletResponse response)
>        throws Exception {
>
>        //TODO: Database based initialization of the countries collection
>        DynaActionForm dynaform = (DynaActionForm) actionForm;
>        HttpSession session = request.getSession();
>        String forSalePropertiesSearchCheckSum = (String) 
> session.getAttribute(Constants.FOR_SALE_CHECK_SUM);
>        String newForSalePropertiesSearchCheckSum = null;
>
>        Integer[] urbanAreas = (Integer[]) dynaform.get("urbanAreas");
>        Integer priceRangeStart = (Integer) dynaform.get("priceRangeStart");
>        Integer priceRangeEnd = (Integer) dynaform.get("priceRangeEnd");
>        Integer[] propertyTypes = (Integer[]) dynaform.get("propertyTypes");
>
>        HashGenerator hashGenerator = new HashGenerator();
>                    hashGenerator.add(urbanAreas,"urbanAreas");
>                    hashGenerator.add(priceRangeStart,"priceRangeStart");
>                    hashGenerator.add(priceRangeEnd,"priceRangeEnd");
>                    hashGenerator.add(propertyTypes,"propertyTypes");
>                    newForSalePropertiesSearchCheckSum = 
> hashGenerator.getHash();
>
>            if(forSalePropertiesSearchCheckSum != null && 
> forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)) {
>                System.out.println("Checksums match");
>            }
>
>        if (forSalePropertiesSearchCheckSum == null
>            || 
> !forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)){
>
>            Set forSaleProperties =
>                findForSaleProperties(
>                    urbanAreas,
>                    priceRangeStart,
>                    priceRangeEnd,
>                    propertyTypes);
>
>session.setAttribute(Constants.FOR_SALE_PROPERTIES_SEARCH_RESULT, 
>forSaleProperties);
>            session.setAttribute(
>                Constants.FOR_SALE_CHECK_SUM,
>                newForSalePropertiesSearchCheckSum);
>//                TODO:Add logging functionality
>                System.out.println("Returning fresh search results");
>
>        } else
>        /*
>                  if (
>
>session.getAttribute("forSalePropertiesSearchCheckSum").equals(
>                        forSalePropertiesSearchCheckSum))
>                 */
>            {
>            //This means that it is the same search, just called again.
>            //TODO:Add logging functionality
>            System.out.println("Returning cached search results");
>
>
>        }
>
>        //TODO: Decent logging is needed here
>        System.out.println(forSalePropertiesSearchCheckSum);
>        System.out.println(newForSalePropertiesSearchCheckSum);
>        System.out.println(" ---------------------------------------" );
>
>        return actionMapping.findForward("success");
>        }
>}
>
>=snip
>
>
>
>
>Christina Siena wrote:
>
>>I recently developed an application with a complex UI. One of the pages 
>>required querying the database based on user selection and re-displaying 
>>the page with the retrieved data and any previous existing user 
>>selections. Four different fields can trigger a db query resulting in 
>>page re-display and validations can also result in page re-display. Each 
>>time the page is re-displayed, the "state" of the page must be 
>>"remembered" from the last time it was displayed. (still with me so far?) 
>>Most of the data re
>>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
>For additional commands, e-mail: user-help@struts.apache.org
>
>



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


Re: some best practices questions

Posted by Bryan Hunt <ad...@revoltingdigits.com>.
Sorry if this is considered spamming the list ....

Speaking of storing stuff in session scope. I've developed what I think 
is a handy class which I think it useful for
when I want to store something like a search in a session variable.

For instance if I want to page through it ( using displaytags.org (10 
out of 10)) or simply if I don't want to fetch
from the database time and time again.
By default the data expires on an hourly basis. And if a different 
combination of parameters is sent it expires
the cached stuff.

Here is the class

snip=
package ie.jestate.struts.client;

import java.util.Date;

/**
 * @author Bryan Hunt
 */
//TODO:Perhaps I should be generating a MD5 or something but I can't see 
a good reason to use any more CPU

public class HashGenerator {
   
    private StringBuffer buffer;
   
   
    /**
     *
     */
    public HashGenerator() {
        super();
        buffer = new StringBuffer(50);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param urbanAreas
     */
    public void add(Integer[] array,String fieldname) {
        for (int i = 0; i < array.length; i++) {
            Integer integer = array[i];
            buffer.append(integer);
        }
        buffer.append(fieldname);
        buffer.append("-");
    }

    /**
     * @param priceRangeStart
     */
    public void add(Integer integer,String fieldname) {
        // TODO Auto-generated method stub
        buffer.append(integer);
        buffer.append(fieldname);
        buffer.append("-");
    }

    /**
     * @return
     */
    public String getHash() {
       
        //I append the hour onto the end of the string so that a hash will
        //only be good for a max of one hour.
        Date date = new Date();
       
        return buffer.toString()+ "-" + new Integer(date.getHours());
    }

}

=snip

And here is example usage.
snip=
/*
 * Created on 24-Jun-2004
 */
package ie.jestate.struts.client;

import ie.jestate.struts.BaseAction;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;

/**
 * @author Bryan Hunt
  *
 */
public class ForSaleSearchAction extends BaseAction {

    /* (non-Javadoc)
     * @see 
org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, 
org.apache.struts.action.ActionForm, 
javax.servlet.http.HttpServletRequest, 
javax.servlet.http.HttpServletResponse)
     */
    public ActionForward execute(
        ActionMapping actionMapping,
        ActionForm actionForm,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception {

        //TODO: Database based initialization of the countries collection
        DynaActionForm dynaform = (DynaActionForm) actionForm;
        HttpSession session = request.getSession();
        String forSalePropertiesSearchCheckSum = (String) 
session.getAttribute(Constants.FOR_SALE_CHECK_SUM);
        String newForSalePropertiesSearchCheckSum = null;
       
        Integer[] urbanAreas = (Integer[]) dynaform.get("urbanAreas");
        Integer priceRangeStart = (Integer) dynaform.get("priceRangeStart");
        Integer priceRangeEnd = (Integer) dynaform.get("priceRangeEnd");
        Integer[] propertyTypes = (Integer[]) dynaform.get("propertyTypes");
       
        HashGenerator hashGenerator = new HashGenerator();
                    hashGenerator.add(urbanAreas,"urbanAreas");
                    hashGenerator.add(priceRangeStart,"priceRangeStart");
                    hashGenerator.add(priceRangeEnd,"priceRangeEnd");
                    hashGenerator.add(propertyTypes,"propertyTypes");
                    newForSalePropertiesSearchCheckSum = 
hashGenerator.getHash();
       
            if(forSalePropertiesSearchCheckSum != null && 
forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)) 
{
                System.out.println("Checksums match");
            }
       
        if (forSalePropertiesSearchCheckSum == null
            || 
!forSalePropertiesSearchCheckSum.equals(newForSalePropertiesSearchCheckSum)){

            Set forSaleProperties =
                findForSaleProperties(
                    urbanAreas,
                    priceRangeStart,
                    priceRangeEnd,
                    propertyTypes);
            
session.setAttribute(Constants.FOR_SALE_PROPERTIES_SEARCH_RESULT, 
forSaleProperties);
            session.setAttribute(
                Constants.FOR_SALE_CHECK_SUM,
                newForSalePropertiesSearchCheckSum);
//                TODO:Add logging functionality
                System.out.println("Returning fresh search results");
           
        } else
        /*
                  if (
                    
session.getAttribute("forSalePropertiesSearchCheckSum").equals(
                        forSalePropertiesSearchCheckSum))
                 */
            {
            //This means that it is the same search, just called again.
            //TODO:Add logging functionality
            System.out.println("Returning cached search results");
           

        }
       
        //TODO: Decent logging is needed here
        System.out.println(forSalePropertiesSearchCheckSum);
        System.out.println(newForSalePropertiesSearchCheckSum);
        System.out.println(" ---------------------------------------" );
       
        return actionMapping.findForward("success");
        }
}

=snip




Christina Siena wrote:

>I recently developed an application with a complex UI. One of the pages required querying the database based on user selection and re-displaying the page with the retrieved data and any previous existing user selections. Four different fields can trigger a db query resulting in page re-display and validations can also result in page re-display. Each time the page is re-displayed, the "state" of the page must be "remembered" from the last time it was displayed. (still with me so far?) Most of the data re
>  
>

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