Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load and store global variables in Jersey/Glassfish

I am creating a RESTful Web Service that wraps an antiquated vendor API. Some external configuration will be required and will be stored on the server either in a file or rdbms. I'm using Jersey 1.11.1 in Glassfish 3.1.2. This configuration data is all in String key/value format.

My first question is this - where can I store global/instance variables in Jersey so that they will be persisted between requests and available to all resources? If this was a pure Servlet application I would use the ServletContext to accomplish this.

The second part to the question is how can I load my configuration once the Jersey server has loaded? Again, my Servlet analogy would be to find the equivalent to the init() method.

like image 797
Graham Avatar asked May 12 '13 02:05

Graham


2 Answers

@Singleton @Startup EJB matches your requirements.

@Singleton
@Startup // initialize at deployment time instead of first invocation
public class VendorConfiguration {

    @PostConstruct
    void loadConfiguration() {
        // do the startup initialization here
    }

    @Lock(LockType.READ) // To allow multiple threads to invoke this method
                         // simultaneusly
    public String getValue(String key) {
    }
}


@Path('/resource')
@Stateless
public class TheResource {
    @EJB
    VendorConfiguration configuration;
    // ...
}

EDIT: Added annotation as per Graham's comment

like image 104
pdudits Avatar answered Nov 11 '22 11:11

pdudits


You can use a listener for init the variables and set to the context as attribute before the web application start, something like the following:

package org.paulvargas.shared;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class LoadConfigurationListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        // read file or rdbms
        ...
        ServletContext context = sce.getServletContext();
        // set attributes
        ...
    }

    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        // remove attributes
        ...
    }

}

This listener is configured in the web.xml.

<listener>
    <listener-class>org.paulvargas.shared.LoadConfigurationListener</listener-class>
</listener>

You can use the @Context annotation for inject the ServletContext and retrieving the attribute.

package org.paulvargas.example.helloworld;

import java.util.*;

import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@Path("/world")
public class HelloWorld {

    @Context
    private ServletContext context;

    @GET
    @Produces("text/plain; charset=UTF-8")
    public String getGreeting() {

        // get attributes
        String someVar = (String) context.getAttribute("someName")

        return someVar + " says hello!";
    }

}
like image 8
Paul Vargas Avatar answered Nov 11 '22 11:11

Paul Vargas