2013-04-04 13 views
7

Come posso visualizzare un messaggio di successo e quindi reindirizzare l'utente a un'altra pagina dopo un timeout di es. 5 secondi?Mostra messaggio di successo e quindi reindirizza a un'altra pagina dopo un timeout utilizzando PageFlow

Ho bisogno di questo per la pagina di accesso dopo un accesso riuscito. Ho provato quanto segue e posso vedere il messaggio di avviso in caso di errore di accesso, ma non il messaggio di successo sul successo di accesso. Mostra immediatamente la pagina di destinazione.

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"; 
     } 
    } 

Sto utilizzando PageFlow di Seam per la navigazione.

Ho un

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

nella pagina di accesso.

risposta

6

Prima di tutto, con il codice che hai postato non vedrai il FacesMessage prima del reindirizzamento, lo vedrai dopo il reindirizzamento. Inoltre, per fare in modo che ciò accada, è necessario aggiungere un filtro, poiché i messaggi vengono persi durante il reindirizzamento. Questo è il codice per il filtro è necessario (non dimenticate di dichiararla in 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; 
} 
} 

Se questo non funziona per voi, e avete bisogno di mostrare il messaggio prima, allora si Dovremo fare qualcosa di simile al seguente: rendere il metodo return void, invocarlo tramite ajax, e dopo aver aggiunto il messaggio di successo, invoca qualche metodo javascript che attenderà un paio di secondi e poi eseguirà il reindirizzamento (magari facendo clic a livello di codice di un pulsante nascosto che reindirizza alla pagina successiva). Secondo me non ne vale la pena, si limiterà a ritardare la procedura di accesso. Comunque utente saprà tha tlogin riuscito perché sarà reindirizzato alla home page (o qualsiasi pagina che lui di inviare)

EDIT: i messaggi vengono visualizzati nella pagina quando il metodo termina, così in attesa nel gestito il metodo bean non funzionerà. dopo aver aggiunto la FacesMessage, utilizzare

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

E nel vostro xhtml, è necessario avere una funzione javascript simile a questo:

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

dove hiddenButtonId è l'ID di ap: pulsante che reindirizza a home page ed è nascosto (display: nessuno)

Ma ancora, questo è un approccio sgradevole, a mio parere non c'è bisogno di fare questo, si ritarderà solo il processo di accesso.

+0

Ciao @Damian, sto lavorando con ajax, ho provato Thread.currentThread() del sonno (5000); lascia la pagina in attesa di 5 secondi ma il messaggio mostra dopo il reindirizzamento, voglio solo mostrare il messaggio prima del reindirizzamento con quel metodo grazie !! – Holysh

+0

Si noti che questo è un JSF 1.x soluzione mirata. In JSF 2.x c'è un modo molto più bello di utilizzare l'ambito del flash. – BalusC

+0

@Holysh Ho modificato la risposta per spiegare come rendere il messaggio visualizzato PRIMA del reindirizzamento. – Damian

14

È una delle utilità di Flash. Invece di

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

semplicemente utilizzare questo codice

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

La chiamata 'setRedirect()' non è necessaria. Si prega di notare che il messaggio verrà visualizzato nella pagina di destinazione e quindi l'OP deve avere un '' laggiù. – BalusC

+0

Ciao @BalusC stavo aspettando la tua risposta :) sì funziona con il mio codice e anche con il codice fornito dall'utente ..., ma il problema è come posso mostrare il messaggio prima del reindirizzamento poi dopo 5 secondi ad esempio reindirizzare ad un altro pagina – Holysh

+0

Ciao Balus, qual è l'utilità esatta di setRedirect? – user1643352

0

non è possibile dichiarare MultiPageMessagesSupport nel web.xml è necessario dichiarare MultiPageMessagesSupport in faces-config.xml. . Por esempio:

enter code here 

<lifecycle> 
    <phase-listener>your.package.MultiPageMessagesSupport</phase-listener> 
</lifecycle>