Request and session scoped variables
To create a variable that can safely be
accessed in the request or session scope, use the following two classes
in the gw.api.web package:
RequestVar– Instantiate this class to create a request-scoped variable stored in the web requestSessionVar– Instantiate this class to create a session-scoped variable stored in the web session
These classes create a variable with a well-defined life cycle and attachment point of either the request or session. Use the set method to set the variable value. Use the get method to get the variable value.
In the base configuration, these classes do not work in the context of web service
implementation or Gosu servlet classes. To enable web services and Gosu servlets as valid sources for variables in
a RequestVar object, enable the ScopedVariableSupportedForAllCapturedRequests
configuration parameter.
For both objects, Gosu provides a RequestAvailable property. Check
the value of this boolean
property to see if the RequestVar
object has a request or the SessionVar
object has a session available in this programming context. For example,
if the code was called from a non-web unit test or a batch process, these
properties return false.
If RequestAvailable returns
false, it is unsafe to
call either get or set methods on the property. From
Java, these properties appear as the isRequestAvailable
method on each object.
RequestVar and SessionVar, always use RequestAvailable before trying
to access the variable. Always handle the variable not being available
or having a value of null.
The recommended pattern for concurrent
use is to store the instance of the variable as a class variable declared
with the static keyword.
By using the static keyword
on the class, many programming contexts can access the same session variable
or request variable. Use the generics syntax SessionVar<TYPE> when you define the variable.
For example, to store a String
object, define the type as SessionVar<String>.
For example:
class MyClass {
static var _varStoredInSession = new SessionVar<String>()
static property get MySessionVar() : String {
if (_varStoredInSession.RequestAvailable) {
return _varStoredInSession.get()
} else {
return null // ENSURE THE CALLER CHECKS FOR NULL
}
}
static property set MySessionVar(value: String) {
if (_varStoredInSession.RequestAvailable) {
_varStoredInSession.set(value)
} else {
// decide what to do if the request is not available
}
}
}
In any other part of the application, you can write code that sets this property:
MyClass.MySessionVar = "hello"In another part of the application, you can write code that gets this property:
print( MyClass.MySessionVar )This example explicitly checks
the RequestAvailable property.
In business code, for example to support your batch processes, you must
decide what to do if RequestAvailable
returns false.
Using RequestVar
and SessionVar is strongly
recommended, rather than the Java thread local API java.lang.ThreadLocal<TYPE>. Because application servers
pool their threads, using ThreadLocal
increases the risk of data remaining forever as a memory leak, because
the thread to which you attached it never terminates. Also, pooled threads
can preserve stale data from a previous request, because the server thread
pool reuses the thread for future requests. If you ever use a ThreadLocal, it is critical to
be very careful to clean up all code with a try/finally block. Better practise
is to convert that code to use RequestVar
and SessionVar.
See also
