struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Struts Wiki] Update of "RolloverScope" by MichaelJouravlev
Date Thu, 14 Sep 2006 23:03:42 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Struts Wiki" for change notification.

The following page has been changed by MichaelJouravlev:
http://wiki.apache.org/struts/RolloverScope

------------------------------------------------------------------------------
  Attention! This page describes a feature that has not been implemented yet!
  
- = Rollover Scope =
+ = Rollover Scope for Struts 1.3.x =
  
- In addition to standard J2EE scope objects (request, session, applicaiton) Struts supports
the rollover scope. This is a virtual scope, which for most uses and purposes is identical
to request scope, but its content survives till the next request comes in.
+ In addition to standard J2EE scope objects (request, session, applicaiton) Struts will support
the ''rollover scope''. Ideally, for most uses and purposes this scope should be identical
to request scope, but its content should be stored on the server until the next request comes
in. Hence the name, the content of the scope rolls over to a next request.
  
- The major reason for implementing rollover scope is automatic retaining of !ActionForm object
for its content to be displayed on a consecutive request (redirect-after-post pattern).
+ One of the reasons for implementing rollover scope is automatic retaining of an !ActionForm,
so its content to be displayed on a consecutive request (redirect-after-post pattern). Using
session-scoped forms requires manual memory cleanup, which is tedious.
  
- === Storing data in rollover scope ===
+ == A high-level outline of a rollover scope ==
  
- When an object is stored in rollover scope, the object is actually stored in the request
scope. Also the reference to the object is stored in rollover scope container. If container
does not exist, it is created in request scope.
+ When an object is stored in rollover scope, the object is actually stored in the request
scope. An additional reference to the object is stored in rollover scope container. If container
does not exist, it is created and is stored itself in the request scope.
  
  When an object is accessed from rollover scope, the data is actually read from the request
scope.
  
- Before returning the response to a client Struts verifies whether a rollover container exists.
If yes, the container is saved in the session scope. A uniqie (for a given session) cookie
is created and is attached to the response.
+ Before returning the response to a client Struts verifies whether a rollover container exists
in request scope. If yes, the container is saved into the session scope. On a next request,
Struts checks whether the session contains a rollover container. If yes, its content is moved
to the request scope and rollover container is disposed of.
  
- === Handling an incoming request ===
+ This approach allows to present rollover-scoped objects as request-scoped objects to an
application in most cases. When an application accesses rollover scope, it actually accesses
the request scope. Struts tags or JSTL tags automatically pick up data saved in rollover scope
because this data has been copied back to request scope. Thus, no additional support is nesessary
for tag libraries.
  
- Struts checks whether the request contains rollover cookie. If yes, session is looked up
for a rollover scope that corresponds to the cookie and content of rollover scope is copied
to the request object. The rollover container is not recreated. (Unique cookies are used as
IDs of rollover containers in the session object, this allows to have several rollover containers,
thus allowing to open several browser windows that use the same !ActionForm type.) Response
object is updated to ensure that the rollover cookie expires on next request.
+ Without additional handling, the rollover-scoped object can be instantiated only once for
a given session, because the rollover scope is stored in the session between requests. This
is a limitation of the current implementation. The ways to overcome it are outlined further.
  
- When user code accesses rollover scope, it actually accesses the request scope. Struts tags
or JSTL tags automatically pick up data saved in rollover scope because this data has been
copied back to request scope. Thus, no additional support is nesessary for tag libraries.
+ == ActionForm and rollover scope ==
  
- === ActionForm and rollover scope ===
+ An !ActionForm can be configured to be stored in the rollover scope using {{{scope="rollover"}}}
in an action mapping configuration, for example:
  
- An !ActionForm can be configured to be stored in the rollover scope using {{{scope="rollover"}}}
in an action mapping configuration.
+ {{{<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>
  
- === 1.2 and 1.3 compatibility ===
+ <action path = "/loginrenderaction"
+        type = "com.acme.LoginRenderAction"
+        name = "loginform"
+        scope = "rollover"
+        validate = "false">
+  <forward name = "notloggedin" path = "/pages/login.jsp"/>
+  <forward name = "loggedin" path = "/pages/logout.jsp"/>
+ </action>}}}
  
- Rollover scope is implemented both in 1.2-style RequestProcessor as well as 1.3-style Command.
+ == 1.2 and 1.3 compatibility ==
  
+ Currently the rollover scope is implemented for 1.3-style Command chain only. The DTD is
updated.
+ 
+ == Implementation details ==
+ 
+ === Core files ===
+ 
+ org.apache.struts.chain.context.!ActionContextBase is enhanced so getScope(String scopeName)
accepts rollover context name.
+ org.apache.struts.chain.context.!ActionContext interface is enhanced with getRolloverScope()
method.
+ org.apache.struts.chain.context.!WebActionContext class is enhanced with getRolloverScope()
method.
+ org.apache.struts.chain.commands.servlet.!ExecuteAction class is enhanced to store rollover
scope in the session after an action class is executed.
+ org.apache.struts.chain.commands.!ExecuteCommand class is enhanced to store rollover scope
in the session after an command is executed.
+ 
+ === Reading rollover data from the session ===
+ The base request chain is augmented with {{{ObtainRolloverData}}} class placed before actions,
commands or actionforms are looked up and instantiated:
+ 
+ {{{<command className="org.apache.struts.chain.commands.servlet.SetContentType"/>
+ <command className="org.apache.struts.chain.commands.ObtainRolloverData"/>
+ <command className="org.apache.struts.chain.commands.RemoveCachedMessages"/>}}}
+ 
+ When a request is received, Struts checks whether the session contains a rollover container.
If yes, its content is moved to the request scope and rollover container is disposed of.
+ 
+ === Executing a command or an action ===
+ 
+ After either an action or a command has executed by !ExecuteAction or !ExecuteCommand respectively,
but before the response is sent to a browser, a new rollover container is created if needed
and is stored in the session. This container will be checked on a next request.
+ 
+ == Limitations and other approaches ==
+ 
+ Current implementation allows to store only one session-wide instance of an object, so in
a way rollover scope works like a session scope with automatic cleanup when next request comes.
Obviously this is not how actual request-scoped objects behave. Below are the knows options
for improvement.
+ 
+ === Use a URL parameter ===
+ 
+ Stripes generates a URL parameter that allows to locate a proper rollover container object,
called a !FlashScope in Stripes. The drawbacks:
+    * URL is mangled, which may not be desirable for some (like me).
+    * Must redirect to stick the parameter into URL. Redirection is needed for render requests
too, like: render(URL)->redirect->render(URL+param).
+ 
+ === Use a hidden form field ===
+ It is possible to generate a hidden form field with rollover container ID, the drawbacks:
+    * all pages must contain forms
+    * what if a page contains several forms?
+ 
+ === Use a temporary cookie ===
+    The drawbacks:
+    * If cookies are turned off on a browser, would have to use URL parameters
+    * It is not possible (as far as I know) to send one cookie from one browser window and
another from another window; all cookies are shared by all windows in a browser session.
+ 
+ == Conclusion ==
+ 
+ Currently rollover scope is implemented in its simplest and allows only one session-scoped
instance of an object to be rolled over.
+ 

Mime
View raw message