2014-08-07 2 views
3

У меня есть собственный ExceptionHandlerWrapper для управления ViewExpiredException и другими ошибками.Flash-сообщения, не показанные после перенаправления в MyFaces во время работы в Mojarra

Идея состоит в том, чтобы поймать ошибку, добавить сообщение об ошибке и перенаправить (с перенаправлением, а не на навигацию) на индексную страницу, где будет отображаться сообщение об ошибке.

fc.getExternalContext().getFlash().setKeepMessages(true); 
    Messages.addFlashError(null, "my message"); 
    Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash(); 
    flash.put("foo", "hello"); 
    fc.getExternalContext().redirect("index.xhtml"); 

Однако флэш-сообщения не сохраняются (но foo присутствует в области флэш-памяти).

Это работало в mojarra, но я перешел на myfaces 2.2.4, и это остановилось. Есть идеи? (также используя символы 1.8.1) Спасибо.

+0

Очевидно, что ошибка в Myfaces – kolossus

ответ

4

Я смотрел на источник MyFaces и кажется, что они явно нуждаются в дополнительной Flash#setRedirect() вызов на вершине Flash#setKeepMessages(). Хотя Javadoc, по общему признанию, не кристально понятен в этом, я ожидал бы, что вызов setRedirect(true) необходим только для атрибутов Flash, а не для сообщений Flash, у которого есть свой собственный вызов setKeepMessages(true).

Так, в принципе, вы должны делать следующее:

fc.getExternalContext().getFlash().setKeepMessages(true); 
Messages.addFlashError(null, "my message"); 
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash(); 
flash.put("foo", "hello"); 
fc.getExternalContext().getFlash().setRedirect(true); // <-- Add this. 
fc.getExternalContext().redirect("index.xhtml"); 

Однако, как вы уже используете JSF утилиту библиотеки OmniFaces, которые уже неявно вызывает setKeepMessages(true) при использовании Messages#addFlashXxx() методов, а также неявно вызывает setRedirect(true) при использовании Faces#redirect() метод, вы могли бы сойти с рук только в следующем, который делает точно так же, как и выше «беспорядок»:

Messages.addFlashGlobalError("my message"); 
Faces.setFlashAttribute("foo", "hello"); 
Faces.redirect("index.xhtml"); 

Нет необходимости ф или пользовательский фазовый прослушиватель.

+0

Что делает 'Flash # setRedirect()' на самом деле? – Tiny

+0

@ Tiny: Он намерен позволить флеш-сообщениям пережить двойное перенаправление, если оно есть. – BalusC

0

Я временно решил это с помощью PhaseListener. Я не люблю его, но он работает сейчас

Что я делаю, когда я добавить флэш-сообщение, я положил его в флэш-рамки:

 Messages.addFlash(null, new FacesMessage(severity, summary, detail)); 

    context.getExternalContext().getFlash().put("messages", context.getMessageList()); 

Тогда я восстановить их в phaseListener

public void beforePhase(final PhaseEvent event) { 
    FacesContext facesContext = event.getFacesContext(); 

    if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) { 
     if (!facesContext.getResponseComplete()) { 
      this.restoreMessages(facesContext); 
     } 
    } 
} 
private int restoreMessages(final FacesContext facesContext) { 
    final Object flash = facesContext.getExternalContext().getFlash().get("messages"); 
    if (flash != null) { 
     List<FacesMessage> messages = (List<FacesMessage>) flash; 


     int restoredCount = messages.size(); 
     for (Object element : messages) { 
      facesContext.addMessage(null, (FacesMessage) element); 
     } 
     return restoredCount; 
    } 
    return 0; 
} 
Смежные вопросы