There are cases where an object must be stored in a place that can be accessed by different parts of an application. For example, an application may store information about the user that is currently logged in, or a selection that the user has made and that affects different parts of the application. But there are also instances that should be shared between all users, for example actual whether data in a flight control system, or a cache for results of frequent calculations.
When storing those data in RAP, it's important to take into account that the Java VM and the file system are shared by multiple users and perhaps even different RAP applications. Thus, the classical Singleton approach should not be used in RAP. When there are multiple users and applications, data must be stored in a place that is suitable for its scope. RAP provides basic data stores for the different scopes.
Especially when an application must handle a lot of parallel user sessions, it's crucial to limit the memory and CPU cycles consumed by a single UI session. Depending on the application, it may be a good idea to share instances of objects that are not user-specific between all users instead of creating an equivalent instance for every single UI session.
An application can store those shared objects as attributes in the ApplicationContext. This makes them accessible for all UI sessions within the application. But in contrast to singletons, the objects won't be available in a different application. When the application is stopped, the application context is cleared and the shared instances can be cleaned up by the garbage collector.
Some shared information are only valid for the current instance of the entrypoint, i.e. the current UI session. As an example, in a call center application, the customer record that is currently selected is only valid for the current UI session. At the same time, another agent is talking to another customer.
Those objects can be stored as attributes in the UISession. The attributes of a UI session will be cleaned up when the UISession ends.
When a user reloads the page in the browser or switches to another entrypoint, a new UI session is created. All information that was stored in the previous UISession is lost. But it's still the same user. Most applications will remember the user and not ask for a login again.
As usual in web applications, information about the current user should be stored in the HttpSession. RAP applications can access the HttpSession using UISession#getHttpSession().
Some applications allow their users to do certain customizations such as choosing between metric vs. imperial units. Those user settings should be preserved for a longer period of time. RAP provides a simple persistent store for this kind of settings, the SettingStore. The setting store identifies a returning user by means of a cookie. The default implementation stores settings in Java .properties files on disk. But the mechanism also allows for custom implementations. An instance can be obtained from RWT.getSettingStore(). In contrast to the other stores, the setting store can only keep strings, not arbitrary objects.
Note that the settings store relies on cookies, which may be deleted or disabled by the user. It is also possible to identify the user by any other means and use the method loadById to initialize the setting store from preserved data.
|Interface / Instance||Scope||used for||life span|
|application||instances shared between all users of an application||entire lifetime of the application, cleared when application is stopped|
|UI session||instances specific to the current UI session||execution of a single entrypoint instance, cleared when UI session expires|
HttpSession (Servlet API)
|user||user-specific information||Http session, cleared on session timeout|
|user (persistent)||Persistent user settings (Strings)||never, cookie lasts 3 month by default|
All these data stores have at least the three methods setAttribute, getAttribute and removeAttribute.
Please keep in mind that these data stores keep data in memory and are not suited for large or sensitive data structures.
A reference to any of these data stores can only be obtained in the the context of a UISession. That is, they are directly accessible from a UI thread, but background threads need to execute code in the context of a UI session (see Threads in RAP).