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. Это обеспечивает более чистый подход.