You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Michael Jouravlev (JIRA)" <ji...@apache.org> on 2006/11/09 02:03:01 UTC

[jira] Commented: (STR-2939) Provide a conversation scope (syn: Flash scope, dialog scope) object to store data between requests.

    [ http://issues.apache.org/struts/browse/STR-2939?page=comments#action_38630 ] 
            
Michael Jouravlev commented on STR-2939:
----------------------------------------


   [[ Old comment, sent by email on Thu, 31 Aug 2006 14:00:53 -0700 ]]

Ok, I have implemented a first draft.

[1]

First, the name. I chose the one that I think is a pretty good one:
Rollover Scope. Meaning that request-scoped data rolls over to a next
request. The name is final, no alternative names please ;-) The name
describes the functionality and at the same time does not give a wrong
impression that it somehow related to wizards, dialogs, flow, etc. On
the other hand, a wizard that uses rollover scope for its ActionForm
works pretty well ;)

[2]

Now the functionality. The rollover scope can be accessed from Action
with a member method, it can also be accessed by reading an object
from HttpServletRequest keyed as ROLLOVER_KEY.

Everything written to rollover scope is written to the request object
too, everything read from rollover scope is looked up in request
object first, then if not found, it is looked up in rollover object
itself. This way rollover data is presented to other parts of
application including JSP tags as regular request-scoped data.

Rollover scope is implemented in the new composable request processor
both for commands and actions. Rollover scope is supported for action
mappings as well, so an action mapping can use scope="rollover". Here
is an example of a login component implemented with two action
mappings and two corresponding actions.

<action path = "/logininputaction"
        type = "com.acme.LoginInputAction"
        name = "loginform"
        scope = "rollover"
        validate = "false"
        parameter = "initEvent=init,loginEvent=login,logoutEvent=logout">
  <forward name = "render" path = "/loginrenderaction.do" redirect = "true"/>
</action>

<action path = "/loginrenderaction"
        type = "com.acme.LoginRenderAction"
        name = "loginform"
        scope = "request"
        validate = "false">
  <forward name = "notloggedin" path = "/pages/login.jsp"/>
  <forward name = "loggedin" path = "/pages/logout.jsp"/>
</action>

Login component is normally accessed with "loginrenderaction" URL.
When a user navigates to this location, LoginRenderAction checks
current user stored in the session, and displays either login.jsp page
if no one is logged in, or logout.jsp if there is a logged in user.

login.jsp contains a login form that submits to "logininputaction",
LoginInputAction uses loginform to store username (password is not
stored) in case it has to be redisplayed when credentials are not
correct. When a user submits a form for the first time, Struts checks
whether the loginform exists, it does not, so it creates a form in
rollover scope. After username/password are checked, a user is either
logged in or not, but in both cases he is redirected to
loginrenderaction that either redisplays a login page or shows current
login status. Before the redirection, the loginform is pushed from
request to session because it is defined in rollover scope for
logininputaction.

On the next request the form is pulled from the session into the
request, but *not* into the rollover scope. "loginrenderaction"
redisplays the login page along with error message and shows the login
name entered on previous attempt. Because loginrenderaction defines
the form as request-scoped (see mapping above), the loginform is not
stored in rollover scope, now it is a regular request-scoped form. So
when a user hits "refresh", the form is automatically recreated by
Struts, so the entered username is gone. To prevent this, the form
should be defined with scope="rollover" in both input and render
mappings, this way it will always be saved in the session when request
comes. This allows to refresh the page without losing data.

At the same time, if a user navigates to another page and then comes
back to login page, the entered username will be lost because the
loginform will be recreated. I think this is acceptable for cases like
login.

[3]

Now I am going to add temporary cookies that will identify a rollover
scope, this way one will be able to have as many rollover scopes as
many browser windows are open. The cookie is chosen instead of a
request parameter (like in Stripes) because I want to preserve the URL
intact, it may matter if a developer cares about browser page history.
Thanks Antonio for the tips on storing rollover scope in the request
and on using cookies.

Comments?

Michael.


> Provide a conversation scope (syn: Flash scope, dialog scope) object to store data between requests.
> ----------------------------------------------------------------------------------------------------
>
>                 Key: STR-2939
>                 URL: http://issues.apache.org/struts/browse/STR-2939
>             Project: Struts 1
>          Issue Type: Improvement
>          Components: Core
>            Reporter: Michael Jouravlev
>         Assigned To: Michael Jouravlev
>            Priority: Minor
>
> In addition to standard J2EE scopes (page for JSP, request, session and application) provide a new scope object that would hold data between requests. Similar facilities in Tapestry and Stripes are called FlashScope, Struts 1 will call it as Conversation Scope.
> Physically, this object will be stored in the session object. It will allow the same get/set/remove operations as other scopes. The objects placed in this scope will be removed two roundtrips after they were placed (they are intended to be used after the first roundtrip). The object lifetime can be increased by increasing a corresponding roundtrip counter.
> Struts 1.2.x introduced storing messages in the session with their automatic cleanup after they are used, usually in a JSP page. Therefore, Struts 1.2.x has a rudimentary Conversation Scope for messages only. Retrofit mesage handling, queue messages to Conversation scope.
> * Provide direct access to Conversation scope from Action (create a method)
> * Update saveMessages to accept Conversation scope
> * For classes other than Action provide an utility method in RequestUtils
> * Allow using Conversation scope in an action mapping definition for ActionForms.
> From developer's point of view usage of ActionForms in Conversation scope + redirect to view should be similar to usage of ActionForms in request scope and forwarding to view. Ideally it should be possible to retrofit statelless actions that forward to JSPs to Conversation actions that redirect to views by only changing the scope of an ActionForm in an action mapping.
> What the whole thing is for? To be able to use redirection without worrying about garbage in the session. Redirection allows to provide better user experience, in particular related to navigation and double submit.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira