Jersey / ServletContext and resource loading on startup

14,520

Solution 1

I am not familiar with Jersey, but generally in a Java web application, I think the right thing to do would be to create a ContextListener.

A context listener is a class that implements the interface javax.servlet.ServletContextListener and is configured in your web.xml. It has a method that is executed when the application is first loded into your container, and another one that is executed when the application is stopped, so it is the ideal place to put some one-time initialization stuff, and clean-up things before the application is stopped.

So the steps are :

  1. create your Listener class, implement the contextInitialized(ServletContextEvent sce) method. In this method you receive a ServeltContextEvent that has getServletContext() method that gives you access to the ServletContext.
  2. Configure your Listener in your web.xml

You'll find additional info here : tutorial

Or on Sun's, er, Oracle's site.

By the way, if your file will be in a JAR file I am not sure that the ServletContext method is the best way to load it. I think you're better off with somethinbg like :

this.getClass().getClassLoader().getResourceAsStream("com.company.my.file.properties");

Solution 2

Using a ContextListener isn't the JAX-RS way to do this-- the ContextListener is the "next layer down," as it were, in the servlet API.

You can put the annotated declaration in the constructor parameters and it will be passed to the constructor:

public Servlet(@Context ServletContext context) {

Using the @Context annotation for a data member initializes that member after the object is constructed, as you discovered.

Another way to do this is to move the initialization of the Config object into some sort of init call, and only initialize it when it's needed, i.e. lazy initialization. Then the ServletContext data member will already have been set by the Jersey framework.

Good Luck!

Kirk

Share:
14,520

Related videos on Youtube

Raphael Jolivet
Author by

Raphael Jolivet

A random Geek, living in the south of France.

Updated on April 23, 2022

Comments

  • Raphael Jolivet
    Raphael Jolivet about 2 years

    I'm kind of new in web development with Java. I am developing a web service and I've chosen REST / Jersey for it.

    I want to init some stuff on startup of the service and to keep them all along the life of the service.

    First question : Is the constructor of the Jersey Servlet a good place to do that ?

    Basically, what I want to do is to load a config.ini file located in my WEB-INF directory. Following this help, I understand I need a ServletContext to load my file as a resource.

    However, it is not clear to me how to get this ServletContext in a Jersey Servlet, as it is not really an instance of a servlet, but rather a POJO with some annotations. I wanted to try this tip, but the attribute "context" is null in the constructor. I think that Jersey might populate it after the constructor. Right ?

    So how is the right way to do this ?

    Here is my code so far :

    /** Main REST servlet */
    @Path("/")
    public class Servlet {
    
        // ---------------------------------------------------- 
        // Constants                     
        // ---------------------------------------------------- 
    
        static private final String CONFIG_PATH = "/WEB-INF/config.ini";
    
        // ---------------------------------------------------- 
        // Attributes                     
        // ---------------------------------------------------- 
    
        /** Context */
        @Context ServletContext context;
    
        // ---------------------------------------------------- 
        // Constructor                     
        // ---------------------------------------------------- 
    
        /** Init the servlet */
        public Servlet() {
    
            // Load config.ini from WEB-INF
            Config.config = new Config(
                    this.context.getResourceAsStream(CONFIG_PATH));
    
            // FAIL! this.context is null ...
    
        }
    
        // ---------------------------------------------------- 
        // URI Handlers                    
        // ---------------------------------------------------- 
    
        /** Welcome page */
        @GET
        @Path("/")
        @Produces(MediaType.TEXT_HTML)
        public String welcome() {
            return "<h1>Hi there.</h1>";
        }
    }
    

    Any help would be much appreciated. Thanks in advance,

    Raphael

  • Raphael Jolivet
    Raphael Jolivet almost 14 years
    Hi, thanks for your help. This seems more clear this way, and this works !
  • Russ Bateman
    Russ Bateman over 11 years
    Not sure what you did as this doesn't work: Jersey eats it and the code, as written in the tutorial, is never called under a Jersey ReST servlet.
  • Marcello de Sales
    Marcello de Sales over 10 years
    You can declare that as a property of the class in case multiple methods need to receive the same... It is injected automatically, and it is easier. No need to pass it in the constructor!