Jersey - нулевые значения переменных ресурсов, несмотря на ненулевую инициализацию

У меня есть ресурс в моем REST API Джерси, который имеет частную переменную экземпляра:

@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);
    }
}

При запуске / перезапуске сервера переменная экземпляра someString инициализируется во время contextInitialized() и правильно распечатан. Однако, когда я установил GET запросить http://localhost:8080/myapp/api/test (т.е. вызывать test() метод выше) переменная someString является null,

Как я могу предотвратить это?

2 ответа

Решение

Из спецификации JAX-RS:

По умолчанию новый экземпляр класса ресурса создается для каждого запроса к этому ресурсу.

Таким образом, любое состояние, которое вы устанавливаете в своем экземпляре класса ресурса, не имеет смысла, так как экземпляр никогда не используется снова. Если вы хотите сохранить значение, поместите его в атрибуты ServletContext:

// 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));
}

Хранение значений в static Поля потребуют от вас реализации безопасности потоков и не будут работать в распределенной производственной среде.

Я считаю, что это должен быть комментарий, но у меня недостаточно репутации. Поэтому я пишу как ответ.

Этот вопрос дает пример аннотации @Singleton. Это обеспечивает более чистый подход.

Другие вопросы по тегам