Подтвердить что ты не робот

Как получить и установить глобальный объект в контексте сервлета Java

Интересно, может ли кто-нибудь посоветовать: у меня есть сценарий, когда запланированное задание, выполняемое Quartz, будет обновлять каждый день аррайалист объектов.

Но мне нужен этот arraylist объектов для видимости для всех сеансов, созданных Tomcat. Итак, я думаю, что я пишу этот объект где-то каждый час из задания Quartz, которое выполняется, чтобы каждый сеанс мог получить к нему доступ.

Кто-нибудь может сказать, как это может быть достигнуто? Мне интересно, как объект записывается в контекст сервлета из задания Quartz? Альтернативой является то, что каждый сеанс заполняет аррайалист объектов из таблицы базы данных.

Спасибо

Г-н Морган.

4b9b3361

Ответ 1

Да, я бы сохранил список в ServletContext как атрибут области приложения. Вытягивание данных из базы данных вместо этого, вероятно, менее эффективно, так как вы только обновляете список каждый час. Создание ServletContextListener может потребоваться, чтобы дать задаче Quartz ссылку на объект ServletContext. ServletContext может быть получен только из классов, связанных с JavaEE, таких как Servlets и Listeners.

EDIT: В ServletContextListener, когда вы создаете задание, вы можете передать список в задание, добавив его в JobDataMap.

public class MyServletContextListener implements ServletContextListener{
  public void contextInitialized(ServletContextEvent event){
    ArrayList list = new ArrayList();

    //add to ServletContext
    event.getServletContext().setAttribute("list", list);

    JobDataMap map = new JobDataMap();
    map.put("list", list);
    JobDetail job = new JobDetail(..., MyJob.class);
    job.setJobDataMap(map);
    //execute job
  }

  public void contextDestroyed(ServletContextEvent event){}
}

//Quartz job
public class MyJob implements Job{
  public void execute(JobExecutionContext context){
    ArrayList list = (ArrayList)context.getMergedJobDataMap().get("list");
    //...
  }
}

Ответ 2

Вы можете попробовать некоторое решение для кеширования, например EhCache, чтобы сохранить ваши значения и обновлять их каждый час. Он будет обрабатывать проблемы concurrency. Сам объект кеша может быть сохранен в ServletContext

Хорошим способом записи в ServletContext из задания Quartz является регистрация слушателей на вашем задании, которые получают уведомление об измененном значении. Так, например:

public class JobListener {
    public void updateValue(Object newValue);
}

public class ServletContextCacheJobListener implements JobListener {
     private ServletContext ctx;
     public ServletContextJobListener(ServletContext ctx) {
         this.ctx = ctx;
     }

     public void updateValue(Object newValue) {
          Cache cache = (Cache) ctx.getAttribute("cache");
          cache.update("yourKey", newValue);
     }
}

У вашего задания будет List<JobListener>, и когда вы планируете задание, вы создаете конкретный прослушиватель и добавляете его в задание.

Ответ 3

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

Объектом, который определен и гарантирован (глобальнее) является ServletContext. Это разделяется между всеми сервлетами, входящими в состав одного приложения, то есть загруженным из того же web.xml. Есть put и get вызовы ServletContext, которые позволяют рассматривать его по существу как карту.

Кроме того, вам нужно будет найти классы, общие для всех веб-приложений внутри одного сервера Tomcat. Tomcat делает много работы с загрузчиками, и я думаю, что у разных веб-приложений будут разные погрузчики. Вы можете обойти это, написав собственный класс и разместив этот класс в каталогах Tomcat common или shared. Если я правильно понимаю это описание, эти классы будут доступны в ONCE для всех веб-приложений.

Наконец, за пределами одного сервера Tomcat вам понадобится механизм TCP/IP для обмена данными между JVM. Но поскольку я понял ваш вопрос, это не должно быть необходимым.