Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between ResourceConfig and ServletContextListener for Jersey Rest Service

Tags:

java

rest

jersey

I want to initialize a Jersey Rest service and introduce a global application-wide variable which should be calculated at application start up-time and should be available in each rest resource and each method (here indicated by the integer globalAppValue=17, but will be a complex object later).

In order to initialize the service and calculate the value once at start up I found two practices: The general ServletContextListener and the Jersey ResourceConfig method. But I have not understood what is the difference between both of them? Both methods fire at start up (both System.out-messages are printed).

Here is the implementation of my ServletContextListener which works fine:

public class LoadConfigurationListener implements ServletContextListener
{
    private int globalAppValue = 17;

    @Override
    public void contextDestroyed (ServletContextEvent event)
    {
    }

    @Override
    public void contextInitialized (ServletContextEvent event)
    {
        System.out.println ("ServletContext init.");

        ServletContext context = event.getServletContext ();
        context.setAttribute ("globalAppValue", globalAppValue);
    }
}

And this is the implementation of the Jersey Rest ResourceConfig-method in which the ServletContext is not available. Neither is this Application-object later availabe by injection with the resource-methods:

@ApplicationPath("Resources")
public class MyApplication extends ResourceConfig
{
    @Context
    ServletContext context;

    private int globalAppValue = 17;

    public MyApplication () throws NamingException
    {
        System.out.println ("Application init.");

        // returns NullPointerException since ServletContext is not injected
        context.setAttribute ("globalAppValue", 17);
    }

    public int getAppValue ()
    {
        return globalAppValue;
    }
}

This is the way I would like to gain access in the resource methods to the global value:

@Path("/")
public class TestResource
{
    @Context
    ServletContext context;
    @Context
    MyApplication application;

    @Path("/test")
    @GET
    public String sayHello () throws SQLException
    {
        String result = "Hello World: ";

        // returns NullPointerException since application is not injected
        result += "globalAppValue=" + application.getAppValue ();

        // works!
        result += "contextValue=" + context.getAttribute ("globalAppValue");

        return result;
    }
}

So while the classic ServletContextListener works fine I got several problems to use the ResourceConfig/Application, but would prefer this way because it seems to integrate more natively into Jersey. So my question is which way would be the best practice to use. Thanks!

like image 434
tombo_189 Avatar asked Sep 21 '15 08:09

tombo_189


People also ask

What is ResourceConfig?

ResourceConfig() Create a new resource configuration without any custom properties or resource and provider classes.

What is jersey servlet?

Jersey is a Java library for both serving and calling REST (or mainly HTTP, since not everything is REST) APIs. It's build on top of Java EE specifications, so it can be used on any server that implements these specifications, e.g. Tomcat. In your web. xml file you can define multiple servlets.


1 Answers

You could just set a property in the ResourceConfig by just calling property( key, value ).

public MyApplication() {
    property("MyProp", "MyValue");
}

In your resource class, your are only allowed to inject the super abstract class javax.ws.rs.core.Application, which ResourceConfig extends from.

Then what you can do is call one of standard the Application API methods to get set properties. That method of course is named getProperties(), which returns a map of properties.

@Path("/")
public class TestResource
{
    @Context
    Application application;

    @GET
    public String get() {
        String value = (String)application.getProperties().get("MyProp");
    }
}

Also by using the property method on the ResourceConfig, that property is put into a global javax.ws.rs.core.Configuration object, which is also injectable. So instead of Application, you could inject Configuration

@Path("/")
public class TestResource
{
    @Context
    Configuration config;

    @GET
    public String get() {
        String value = (String)config.getProperty("MyProp");
    }
}

See Also:

  • Using a custom hk2 InjectionResolver to inject application configuration for some other interesting ways to inject just the value instead of having to retrieve it from the Application or Configuration
like image 61
Paul Samsotha Avatar answered Sep 24 '22 04:09

Paul Samsotha