Как обрабатывать ViewExpiredException, показывая предупреждение JavaScript?

Я прочитал вопрос Обработка ViewExireException/ajax и отображение диалогового окна Primefaces и ответ от BalusC. Я хотел бы обработать ViewExpiredException, показав предупреждение с информацией для обновления страницы. Я принял предложение от BalusC к пользователю RequestContext, чтобы запустить выполнение JavaScript, и я удалил перенаправление JSF, потому что я его не использую:

@Override
public void handle() throws FacesException {
    for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
        ExceptionQueuedEvent event = i.next();
        ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
        Throwable t = context.getException();
        if (t instanceof ViewExpiredException) {
            ViewExpiredException vee = (ViewExpiredException) t;
            try {
                log.info("Catched ViewExpiredException for view {}", vee.getViewId());
                RequestContext.getCurrentInstance().execute("handleViewExpired("+vee.getViewId()+")");
                return;
            } finally {
                i.remove();
            }
        } 
    }
    // At this point, the queue will not contain any ViewExpiredEvents.
    // Therefore, let the parent handle them.
    getWrapped().handle();

}

Проблема в том, что я получил NullPointerException при выполнении метода handle из обработчика wrapped. Я добавил предложение возврата, и после его добавления эффект был таким же:

[30.01.13 15:45:59:140 CET] 0000002e ErrorPageWrit E Произошло исключение ) в org.apache.myfaces.shared_impl.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:156) в my.project.web.handler.ViewExpiredExceptionExceptionHandler.handle(ViewExpiredExceptionExceptionHandler.java:59) в org.apache.myfaces.lifecycle. LifecycleImpl.executePhase(LifecycleImpl.java:191) в org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)

Итак, метод родительского дескриптора выполняется, хотя должен быть возврат из метода (логируется информационная строка).

Я использую PrimeFaces 3.4 и MyFaces 2.0.7, все на WebSphere 7.

Я не понимаю, что здесь происходит. Можно ли добиться того, чего я хочу, и если да, то что я делаю не так?


person Danubian Sailor    schedule 30.01.2013    source источник
comment
Для ребят из MyFaces было бы полезно, если бы вы сообщили версию MyFaces (а тем временем попробуйте последнюю версию и сообщите, если она все еще содержит ошибку).   -  person BalusC    schedule 30.01.2013
comment
То есть вы говорите, что это баг, и код в таком виде вообще должен работать, без возврата в обработку?   -  person Danubian Sailor    schedule 30.01.2013
comment
Для последней версии MyFaces: заголовок stackoverflow.com/questions/14230905/, поэтому проверить невозможно   -  person Danubian Sailor    schedule 30.01.2013


Ответы (1)


Лучшим способом было обработать это исключение на стороне клиента. Это очень просто и совершенно прозрачно:

var originalPrimeFacesAjaxResponseFunction = PrimeFaces.ajax.AjaxResponse;
PrimeFaces.ajax.AjaxResponse = function(data, status, xhr) {
  var errorName = $(data.documentElement).find("error-name").text();
  if (errorName == 'javax.faces.application.ViewExpiredException') {
    alert('View has expired, redirection will follow');
    window.location.reload();
  } else {
    originalPrimeFacesAjaxResponseFunction.apply(this, arguments);
  }
};

Никаких 2 новых классов на сервере, никаких faces-config.xml изменений, это то, что я люблю в программировании.

person Danubian Sailor    schedule 01.02.2013
comment
Извините, но это в javascript в xhtml? Или куда мне его положить? Я только что попробовал в javascript выше форму, которая дает мне ViewExpiredException, и это не работает. Я с Websphere и Richfaces. - person jmlv21104; 03.01.2014