I have a resource in my Jersey REST api that has a private instance variable:
@Path("test")
public class TestResource implements ServletContextListener
{
private String someString;
@GET
public void test()
{
System.out.println("someString " + someString);
}
@Override
public void contextDestroyed(ServletContextEvent ctxt) {
System.out.println("Destroying context");
}
@Override
public void contextInitialized(ServletContextEvent ctxt) {
System.out.println("TestResource initialized!");
someString = "SET";
System.out.println("someString has been set. someString: " + someString);
}
}
On server startup/restart the instance variable someString
is initialized during contextInitialized()
and is correctly printed out. However when I set a GET
request to http://localhost:8080/myapp/api/test
(i.e. invoke the test()
method above) the variable someString
is null
.
How can I prevent that?
From the JAX-RS specification:
By default a new resource class instance is created for each request to that resource.
So, any state you set on your resource class instance is meaningless, since the instance is never used again. If you want to persist a value, place it in the ServletContext’s attributes:
// All classes in the web app share a ServletContext, so attribute names
// need to start with package names to prevent collisions.
private static final String SOME_ATTRIBUTE = TestResource.class.getName() + ".someAttribute";
@Override
public void contextInitialized(ServletContextEvent ctxt) {
System.out.println("TestResource initialized!");
String someString = "SET";
System.out.println("someString has been set. someString: " + someString);
ctxt.getServletContext().setAttribute(SOME_ATTRIBUTE, someString);
}
@GET
public void test(@Context ServletContext context) {
System.out.println("someString " + context.getAttribute(SOME_ATTRIBUTE));
}
Storing values in static
fields will require you to implement thread safety and will not work in a distributed production environment.