There’s only one week to go until the RAP 2.0 release. In this short blog series, I’d like to introduce you to the most important changes. Besides the new protocol, the main theme in RAP 2.0 is the consolidation of our APIs. After six years of RAP 1.x, it was time for a cleanup. In this post, I will explain the foundation of the RAP 2.0 API.
The Pillars of the RAP 2.0 API
In a multi-user and multi-application environment, you have to distinguish between different scopes to avoid mixing up your user’s data. There has been some confusion around the session scope in RAP 1.x. In the new API, the scopes are more explicit as they’re represented by interfaces. The two most important interfaces that you should be familiar with are UISession and ApplicationContext. However, let’s start with the basics, the servlet container.
ServletContext and ApplicationContext
RAP runs on a standard servlet container. A servlet container hosts a number of webapps, each containing servlets and static resources. All servlets of a webapp share the same ServletContext. That is, the ServletContext represents a web application.
A RAP application is represented by an ApplicationContext. Also because it’s a web application in itself, this ApplicationContext is bound to a ServletContext. You can run multiple RAP applications in parallel, e.g. in different web applications, or even different servlet containers in the same VM (e.g. different Jetty instances on different ports). ServletContext and the RAP ApplicationContext have a 1 to 1 relationship. The actual instance of ApplicationContext can be obtained from RWT.getApplicationContext().
The ApplicationContext provides access to application-scoped framework services such as the ResourceManager (actually, RWT.getResourceManager() is now just a shortcut for RWT.getApplicationContext().getResourceManager()). It can also be used to store arbitrary objects as attributes. Whenever you need to share information application-wide, you should store them in the ApplicationContext, rather than keeping them statically.
HttpSession and UISession
When a user connects to a web application, the servlet container creates an HttpSession. To recognize the user in subsequent requests, the session ID is usually stored in a session cookie. The HttpSession is valid until either the browser is closed or it is left unattended for a configurable time (the session timeout).
For every instance of a RAP UI, a separate UISession is created. That means that when a user accesses an entry point, that’s a new UISession. When the user reloads the page in the browser, that’s also a new UISession – but the HTTPSession remains the same. There is a 1 to many relationship between HTTPSesssion and the RAP UISession.
The current instance of a UISession is available from RWT.getUISession(). Just like the ApplicationContext, you can use the UISession to store attributes (actually, UISession replaces the old SessionStore). If you need to share information that is related to the EntryPoint instance (e.g. a selection that the user has made), keep it in the UISession. User-related information should rather be stored in the HttpSession, because it survives a single UISession.
Better Support for Testing
One advantage of the new API structure is that it facilitates test-driven development. In contrast to the RWT class, the new interfaces UISession and ApplicationContext provide non-static methods to access framework services. Hence, these instances can be replaced with mocks in a unit test. We also plan to add methods to the test fixture that allow framework instances to be replaced with mocks.
Better Multi-Tab Support