Прежде всего, с кодом, который вы разместили, вы не увидите FacesMessage до перенаправления, вы увидите его после перенаправления. Но также, чтобы это произошло, вам нужно добавить фильтр, потому что сообщения теряются при перенаправлении. Это код нужного вам фильтра (не забудьте объявить его в web.xml):
public class MultiPageMessagesSupport implements PhaseListener {
private static final long serialVersionUID = 1250469273857785274L;
private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";
@Override
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
/*
* Check to see if we are "naturally" in the RENDER_RESPONSE phase. If we
* have arrived here and the response is already complete, then the page is
* not going to show up: don't display messages yet.
*/
@Override
public void beforePhase(final PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
int msg = this.saveMessages(facesContext);
if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) {
if (!facesContext.getResponseComplete()) {
this.restoreMessages(facesContext);
}
}
}
/*
* Save messages into the session after every phase.
*/
@Override
public void afterPhase(final PhaseEvent event) {
if (event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES ||
event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS ||
event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
FacesContext facesContext = event.getFacesContext();
int msg = this.saveMessages(facesContext);
}
}
@SuppressWarnings("unchecked")
private int saveMessages(final FacesContext facesContext) {
List<FacesMessage> messages = new ArrayList<FacesMessage>();
for (Iterator<FacesMessage> iter = facesContext.getMessages(null); iter.hasNext();) {
messages.add(iter.next());
iter.remove();
}
if (messages.isEmpty()) {
return 0;
}
Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
List<FacesMessage> existingMessages = (List<FacesMessage>) sessionMap.get(sessionToken);
if (existingMessages != null) {
existingMessages.addAll(messages);
} else {
sessionMap.put(sessionToken, messages);
}
return messages.size();
}
@SuppressWarnings("unchecked")
private int restoreMessages(final FacesContext facesContext) {
Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
List<FacesMessage> messages = (List<FacesMessage>) sessionMap.remove(sessionToken);
if (messages == null) {
return 0;
}
int restoredCount = messages.size();
for (Object element : messages) {
facesContext.addMessage(null, (FacesMessage) element);
}
return restoredCount;
}
}
Если это не работает для вас, и вам нужно показать сообщение раньше, вам нужно будет сделать что-то вроде следующего: сделать возврат метода недействительным, вызвать его через ajax и после добавления сообщения об успехе вызвать какой-либо метод javascript который подождет пару секунд, а затем сделает перенаправление (возможно, программным нажатием скрытой кнопки, которая перенаправляет на следующую страницу). На мой взгляд, это не стоит усилий, вы просто задержите процесс входа в систему. В любом случае пользователь будет знать, что tlogin прошел успешно, потому что он будет перенаправлен на домашнюю страницу (или на любую другую страницу, на которую вы его отправляете)
EDIT: сообщения отображаются на странице после завершения метода, поэтому ожидание в методе управляемого компонента не будет работать. после добавления FacesMessage используйте
RequestContext.getCurrentInstance().execute("waitAndRedirect()");
И в вашем xhtml вам понадобится функция javascript, подобная этой:
function waitAndRedirect() {
setTimeout(function() {
hiddenButtonId.click();
}, 2000);
}
где hiddenButtonId — это идентификатор кнопки p:, которая перенаправляет на домашнюю страницу и скрыта (display: none)
Но опять же, это неприятный подход, на мой взгляд, этого делать не нужно, вы просто затянете процесс входа в систему.
person
damian
schedule
04.04.2013