Share variables between JAX-RS requests
Asked Answered
E

1

6

I have what I think is a very basic question about JAX-RS but I somehow can't easily find the answer.

I am trying to refactor a REST service which uses a "standard" Javax servlet -- routing requests to methods by hand -- into an "cleaner" JAX-RS implementation. The current application sets some variables during the servlet init(). It assigns those as attributes of the HttpServlet class so they are available during each doGet() and can be passed as parameters to request processing methods. For clarity, one of these is a ConcurentHashMap that acts as a cache.

Now, with JAX-RS, I can extend Application to set my resource classes. I can also use the @Context annotation in each resource implementation to inject things like ServletContext when processing a request. But I do not know how to similarly inject variables set during application initialization.

I am using the Apache Wink 1.3.0 implementation of JAX-RS.

Exclave answered 18/4, 2013 at 22:2 Comment(2)
Are you using Spring?Sermon
No I am not using Spring.Exclave
S
5

You can use a listener for init the cache 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 CacheListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        Map<String, String> dummyCache = new HashMap<String, String>();
        dummyCache.put("greeting", "Hello Word!");

        ServletContext context = sce.getServletContext();
        context.setAttribute("dummyCache", dummyCache);
    }

    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        context.removeAttribute("dummyCache");
    }

}

This listener is configured in the web.xml.

<listener>
    <listener-class>org.paulvargas.shared.CacheListener</listener-class>
</listener>
<servlet>
    <servlet-name>restSdkService</servlet-name>
    <servlet-class>
        org.apache.wink.server.internal.servlet.RestServlet
    </servlet-class>
    <init-param>
        <param-name>applicationConfigLocation</param-name>
        <param-value>/WEB-INF/application</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>restSdkService</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

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

package org.apache.wink.example.helloworld;

import java.util.*;

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

import org.apache.wink.common.model.synd.*;

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

    @Context
    private ServletContext context;

    public static final String ID = "helloworld:1";

    @GET
    @Produces(MediaType.APPLICATION_ATOM_XML)
    public SyndEntry getGreeting() {

        Map<String, String> dummyCache = 
                       (Map<String, String>) context.getAttribute("dummyCache");

        String text = dummyCache.get("greeting");

        SyndEntry synd = new SyndEntry(new SyndText(text), ID, new Date());
        return synd;
    }

}
Sermon answered 19/4, 2013 at 17:26 Comment(3)
This is close to what I thought: set a servlet attribute during initialization and get it back from the Servlet context during each request. But wouldn't doFilter run during each request. Is there a way that I can access the context during init() of the servlet and set the attribute once?Exclave
@PaulVargas .. I was looking for something similar, but I was looking to start an executorservice in the servletContext , on itialization. Thank you. for your answer :)Lyophilic
Hi, @Dc01_xx Another solution is to use a @Singleton (the Enterprise JavaBean). If I get some time, I will add it to my answer. :-)Sermon

© 2022 - 2024 — McMap. All rights reserved.