Share context data with JAX-RS ResteasyProviderFactory

Spread the words...Share on Google+6Share on Facebook1Tweet about this on Twitter3Share on LinkedIn2Buffer this pageShare on StumbleUpon0Share on Reddit0

Many times we get into situation where we have to pass data from-to multiple layers in our application. An example can be application using interceptors. Suppose we have two interceptors in our application, one for login check and second for putting audit information in database. We want to use the User object from first interceptor, into second interceptor.

In RESTEasy based applications, above functionality can be easily implemented using ResteasyProviderFactory instance. ResteasyProviderFactory is enabled by adding a filter in web.xml file using below definition:

<listener>
  <listener-class>
	 org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
  </listener-class>
</listener>

Now you can easily get the instance of ResteasyProviderFactory in any class in scope of RESTEasy context. So, to share data between interceptors, you will need to do two steps:

1)Set the data in context map

This context data is set using pushContext() method. This method add the data to a thread local stack defined as:

protected static ThreadLocalStack<Map<Class<?>, Object>> contextualData 
						= new ThreadLocalStack<Map<Class<?>, Object>>();

You 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)Get the data from context map

Getting back the data set in 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 wrong data when retrieving in another place in your code.

 ResteasyProviderFactory factory = ResteasyProviderFactory.getInstance();
 factory.popContextData(User.class);

This way you can use ResteasyProviderFactory to share data between multiple layers in your application.

Happy Learning !!

Spread the words...Share on Google+6Share on Facebook1Tweet about this on Twitter3Share on LinkedIn2Buffer this pageShare on StumbleUpon0Share on Reddit0

 

 

Give me your email address and whenever I write any tutorial or discuss any java concept, you will receive a little email in your inbox.

Join 2,872 other subscribers

3 thoughts on “Share context data with JAX-RS ResteasyProviderFactory”

  1. java.lang.ClassCastException: org.jboss.resteasy.spi.ResteasyProviderFactory cannot be cast to org.jboss.resteasy.spi.ResteasyProviderFactory
    at org.jboss.resteasy.spi.ResteasyProviderFactory.getInstance(ResteasyProviderFactory.java:351)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:222)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:680)

    1. It’s class loader issue. Basically RESTEasy jars are available in two places in classpath. If you are using JBoss, then RESTEasy jars should be present in jboss distribution, so don’t include them in your war file.

Want to ask any question? Or suggest anything?