2013-04-04 12 views
7

Jak wyświetlić komunikat o powodzeniu, a następnie przekierować użytkownika na inną stronę po upływie limitu czasu na przykład? 5 sekund?Pokaż komunikat o powodzeniu, a następnie przekierowanie na inną stronę po upływie limitu czasu za pomocą PageFlow

Potrzebuję tego do strony logowania po pomyślnym zalogowaniu. Próbowałem następujących czynności i widzę komunikat ostrzegawczy w przypadku niepowodzenia logowania, ale nie komunikat o powodzeniu powodzenia logowania. Pokazuje natychmiast stronę docelową.

public String check(){ 
     if (username.equals("test") && password.equals("test")) { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Sample info message", "PrimeFaces rocks!")); 
      return "Success"; 
     }else{ 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Sample warn message", "Watch out for PrimeFaces!")); 
      return "Failure"; 
     } 
    } 

Używam strony Seam do nawigacji.

Mam

<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" /> 

na stronie logowania.

Odpowiedz

6

Po pierwsze, z opublikowanym kodem nie zobaczysz FacesMessage przed przekierowaniem, zobaczysz go po przekierowaniu. Ale aby to się stało, musisz dodać filtr, ponieważ wiadomości są tracone podczas przekierowywania. Jest to kod dla filtra trzeba (nie zapomnij zadeklarować w 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; 
} 
} 

Jeśli to nie zadziała, i trzeba zanim wyświetli komunikat, a następnie Będziesz musiał wykonać następujące czynności: spraw, aby metoda powróciła do pustej, wywołaj ją przez ajax, a po dodaniu komunikatu o powodzeniu wywołaj metodę javascript, która będzie czekać kilka sekund, a następnie wykonaj przekierowanie (może przez programowe kliknięcie ukrytego przycisku przekierowuje na następną stronę). Moim zdaniem nie jest to warte problemu, tylko opóźnisz proces logowania. W każdym razie użytkownik będzie wiedział tha tlogin udało, bo on będzie przekierowywać do strony głównej (lub cokolwiek strona go do wysyłania)

EDIT: komunikaty są wyświetlane na stronie, gdy metoda kończy, więc czeka w zarządzanym Metoda fasoli nie będzie działać. po dodaniu FacesMessage użyć

RequestContext.getCurrentInstance().execute("waitAndRedirect()"); 

iw swoim xhtml, musisz mieć javascript funkcję podobną do tej:

function waitAndRedirect() { 
    setTimeout(function() { 
     hiddenButtonId.click(); 
    }, 2000); 
} 

gdzie hiddenButtonId jest identyfikator AP: przycisk, który przekierowuje do strona główna i jest ukryty (display: none)

Ale znowu, to nieprzyjemne podejście, moim zdaniem nie ma potrzeby, aby to zrobić, wystarczy opóźnić proces logowania.

+0

Witam @Damian, pracuję z AJAX, próbowałem Thread.currentThread() sleep (5000); pozwala stronie czekać 5 sekund, ale wiadomość pokazuje po przekierowaniu, po prostu chcę, aby pokazać wiadomość przed przekierowaniem z tą metodą dziękuję !! – Holysh

+0

Należy zauważyć, że jest to JSF 1.x ukierunkowane rozwiązanie. W JSF 2.x jest znacznie przyjemniejszy sposób korzystania z zasięgu błysku. – BalusC

+0

@Holysh Edytowałem odpowiedź, aby wyjaśnić, jak wyświetlić komunikat PRZED przekierowaniem. – Damian

14

Jest to jedno z narzędzi Flash. Zamiast

FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Sample info message", "PrimeFaces rocks!"));: 

po prostu użyć tego kodu

FacesContext facesContext = FacesContext.getCurrentInstance(); 
Flash flash = facesContext.getExternalContext().getFlash(); 
flash.setKeepMessages(true); 
flash.setRedirect(true); 
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Sample info message", "PrimeFaces rocks!")); 
+0

Wywołanie 'setRedirect()' jest niepotrzebne. Zwróć uwagę, że wiadomość pojawi się na stronie docelowej, a zatem OP musi mieć "". – BalusC

+0

Witam @BalusC czekałem twoją odpowiedź :) tak działa z moim kodem, a także z kodem dostarczonym przez użytkownika ..., ale problemem jest jak mogę pokazać komunikat przed przekierowaniem następnie po 5 sekundach na przykład przekierowanie do innego strona – Holysh

+0

Cześć Balus, jaka jest dokładna użyteczność setRedirect? – user1643352

0

nie można zadeklarować MultiPageMessagesSupport w web.xml trzeba zadeklarować MultiPageMessagesSupport na twarzach-config.xml. Por. Na przykład:

enter code here 

<lifecycle> 
    <phase-listener>your.package.MultiPageMessagesSupport</phase-listener> 
</lifecycle> 
Powiązane problemy