2011-12-13 2 views
2

У меня мало знаний по Java EE, но в настоящее время я изучаю ее.Долгосрочная задача в Java EE WebApp + icefaces

Я придумал проект, который включает в себя долговременную задачу (до нескольких минут), вызванную пользователем. Задача состоит из нескольких этапов. Конечно, я хотел бы показать прогресс пользователю.

В проекте используется Java EE с JPA, JSF и Icefaces. Он работает на Glassfish.

Опытный коллега посоветовал следующую картину мне:

  1. Создание без гражданства, асинхронное EJB, который создает объект ответа и обрабатывает запрос
  2. PERSIST объект ответа после каждого шага
  3. В бэк, запрос и отображение объекта ответа

Это хорошо работает. Моя единственная проблема - обновить сайт статуса, чтобы отразить прогресс. В настоящее время я делаю это с простой перезагрузкой страницы JavaScript каждые x секунд.

Знаете ли вы способ/шаблон, чтобы отразить текущий шаг от безстоящего ejb к bean-компоненту jsf? Или, и я бы предпочел, чтобы вы знали способ запросить ценность бэк-бэка каждые x секунд?

Edit:

Я отдаю себе отчет в ICEfaces толчок механизм, но я хочу сайт обновления статуса отсоединяется от расчета EJB по следующим причинам:

  • Подложка боб может уже были уничтожены, потому что пользователь покинул сайт и вернулся позже, чтобы получить результат.
  • Несколько сеансов и, следовательно, для одного пользователя могут существовать несколько компонентов.
  • Имея чистый дизайн

ответ

1

Существует несколько вариантов возврата этой информации. Если EJB живет в одном JVM, , вы можете также использовать некоторую карту Singleton и сохранить прогресс по определенному ключу (идентификатор сеанса).

Если это не так, вам понадобится какое-то разделяемое состояние или comminucation. Есть несколько вариантов

  • магазин его на базе данных доступны из обоих уровней (SQL, JNDI, LDAP - лучшим решением будет иметь ключевое значение магазина, как Redis - если вы его получили)
  • использовать некоторые сообщения, чтобы внести состояние обработки на стороне веб-уровневой
  • магазин состояние в хэш его на стороне EJB уровня, а также обеспечить другой метод SLSB в rtrieve это состояние

Ваш выбор не так просто - все эти решения Чертов с различными способами ,

0

Поскольку вы используете ледовые поверхности, вы можете использовать механизм ICEpush для рендеринга ваших обновлений.

+0

Конечно, но, к несчастью, я не знаю механизма уведомления бэкбона о прогрессе. Бэк-файл также может быть уже уничтожен, и пользователь вернется позже, когда вычисление будет завершено. И из-за инкапсуляции я не хочу, чтобы в EJB был код льда. – Michael

0

Я выполнил это, используя модель опроса с резьбой в сочетании с компонентом ProgressBar.

public void init() 
{ 
    // This method is called by the constructor. 
    // It doesn't matter where you define the PortableRenderer, as long as it's before it's used. 
    PushRenderer.addCurrentSession("fullFormGroup"); 
    portableRenderer = PushRenderer.getPortableRenderer(); 
} 


public void someBeanMethod(ActionEvent evt) 
{ 
    // This is a backing bean method called by some UI event (e.g. clicking a button) 
    // Since it is part of a JSF/HTTP request, you cannot call portableRenderer.render 

    copyExecuting = true; 

    // Create a status thread and start it 

    Thread statusThread = new Thread(new Runnable() { 
     public void run() { 
     try { 
         // message and progress are both linked to components, which change on a portableRenderer.render("fullFormGroup") call 
      message = "Copying..."; 
      // initiates render. Note that this cannot be called from a thread which is already part of an HTTP request 
      portableRenderer.render("fullFormGroup"); 
      do { 
       progress = getProgress(); 
       portableRenderer.render("fullFormGroup"); // render the updated progress 
       Thread.sleep(5000); // sleep for a while until it's time to poll again 
      } while (copyExecuting); 
      progress = getProgress(); 
      message = "Finished!"; 
      portableRenderer.render("fullFormGroup"); // push a render one last time 
     } catch (InterruptedException e) { 
      System.out.println("Child interrupted."); 
     } 
    }); 
    statusThread.start(); 

    // create a thread which initiates script and triggers the termination of statusThread 
    Thread copyThread = new Thread(new Runnable() {   
     public void run() { 
     File someBigFile = new File("/tmp/foobar/large_file.tar.gz"); 
      scriptResult = copyFile(someBigFile); // this will take a long time, which is why we spawn a new thread 
      copyExecuting = false; // this will caue the statusThread's do..while loop to terminate 


     } 
    }); 
    copyThread.start(); 
} 
Смежные вопросы