Many times we get into situations where we have to pass data from-to multiple layers in our application. An example can be an application using interceptors. Suppose we have two interceptors in our application, one for login checks and the second for putting audit information in the database. We want to use the User object from the first interceptor to the second interceptor.
1. Enabling ResteasyProviderFactory
In RESTEasy-based applications, the above functionality can be easily implemented using ResteasyProviderFactory instance. ResteasyProviderFactory is enabled by adding a ResteasyBootstrap in web.xml file:
<listener> <listener-class> org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap </listener-class> </listener>
2. Sharing Context Data
Now we can easily get the instance of ResteasyProviderFactory in any class in the scope of the RESTEasyContext. So, to share data between interceptors, we will need to do two steps:
2.1. Setting Data in Context Map
This context data is set using pushContext() method. This method adds the data to a thread-local stack defined as:
protected static ThreadLocalStack<Map<Class<?>, Object>> contextualData = new ThreadLocalStack<Map<Class<?>, Object>>();
We need to push data as follows:
User user = new User(); //Set some user attributes //Get registered ResteasyProviderFactory instance ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); //Add user into context data map factory.pushContext(User.class, user);
2.2 Getting Data from Context Map
Getting back the data set in the first step is very simple. Use popContextData() method. This context data is thread-local in nature, so you do not need to worry about getting the wrong data when retrieving it in another place in your code.
ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance(); User user = factory.popContextData(User.class);
This way you can use ResteasyProviderFactory to share data between multiple layers in your application.
Happy Learning !!