2012-06-25 19 views
27

Da quanto ho capito, gli oggetti posizionati all'interno dell'ambito Flash in un ciclo di vita delle richieste di facce saranno disponibili per il ciclo di vita delle richieste di facce successive e quindi cancellate.Informazioni su Flash Scope in JSF2

Supponiamo che io ho due pagine:

page01.xhtml:

<h:form> 
    <h:commandButton action="#{page01Bean.action}" /> 
</h:form> 

Page01Bean:

@ManagedBean 
@RequestScoped 
public class Page01Bean { 

     public void action(){ 
      FacesContext.getCurrentInstance().getExternalContext().getFlash().put("fooKey", "fooValue"); 
     } 

} 

page02.xhtml:

<h:outputText value="#{flash.fooKey}"/> 

Così, quando il pulsante di page01.xhtml viene cliccato, un volti richiesta del ciclo di vita (ad esempio del ciclo di vita A) inizia e impostare il valore per il flash sotto la chiave chiamato fooKey

Poi apro un'altra scheda del browser e cercare page02.xhtml. Un altro ciclo di vita delle richieste di facce (ad esempio il ciclo di vita B) inizia a eseguire il rendering di questa pagina. Mi aspettavo che il ciclo di vita B potesse accedere al campo di applicazione del flash del ciclo di vita precedente (cioè il ciclo di vita A) e visualizzare fooValue in page02.xhtml. Tuttavia, non visualizza nulla.

Per favore correggimi quanto frainteso sull'ambito del flash in questo exmaple. Grazie mille

risposta

30

In breve, le variabili memorizzate nella portata del flash sopravviveranno a un reindirizzamento e verranno eliminate successivamente. Questo è veramente utile quando si implementa un pattern Post-Redirect-Get.

Se si tenta di navigare verso un'altra pagina reindirizzando e accedendo agli attributi in fase di caricamento, saranno presenti. Dopo che la richiesta è stata eseguita, i valori nel flash verranno scartati. Ad esempio:

Sei in page1.xhtml e hai un commandLink che reindirizza a una nuova pagina con un metodo come questo (Nota: userò la navigazione implicita).

public String navigateToPageB() { 
    FacesContext.getCurrentInstance().getExternalContext().getFlash().put("param1", "Hello World!"); 
    return "pageB?faces-redirect=true"; 
} 

Quando pageB.xhtml è resa, è possibile accedere a questi valori da espressioni EL quali

<h:outputLabel value="#{flash['param1']}" /> 

che visualizzerà la "Ciao Mondo!" stringa che abbiamo salvato in precedenza in navigatePagineB.

Come per la domanda, aprendo una nuova scheda in Esplora risorse non si accede allo stesso contesto in cui si stava accedendo alla scheda precedente, quindi la variabile non sarà disponibile lì.

23

risposta precedente è corretta, ma solo per completezza vorrei dire che ci sono stati un lot of issues nelle implementazioni Mojarra con tutta questa roba, ma alla fine hanno raggiunto per farlo funzionare correttamente in Mojarra 2.1.27 e 2.2.5 versioni .

Come dice @Gamb, lo scopo dell'ambito del flash è mantenere un parametro attivo mappandolo internamente attraverso il reindirizzamento. Possiamo anche mantenere il parametro attivo più a lungo se ne abbiamo bisogno. A parte il modo menzionato, FacesContext#getCurrentInstance#getExternalContext#getFlash#put, c'è anche la possibilità di impostare il parametro tramite l'espressione EL, usando <c:set />.Ho implementato un test di base seguente SSCCE che mostra una più ampia gamma di opzioni, con due punti di vista:

Bean1

@ManagedBean 
@ViewScoped 
public class Bean1 implements Serializable { 

    /** 
    * Just takes the given param, sets it into flash context and redirects to 
    * page2 
    * 
    * @param inputValue 
    * @return 
    */ 
    public String goPage2(String inputValue) { 
     FacesContext.getCurrentInstance().getExternalContext().getFlash() 
       .put("param", inputValue); 
     return "page2?faces-redirect=true"; 
    } 

} 

page1.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:c="http://java.sun.com/jsp/jstl/core"> 
<h:head /> 
<h:body> 

    <!-- Sets the first flash param at the action method, which redirects to page 2 --> 
    <h:form> 
     <h:inputText value="#{inputValue}" /> 
     <h:commandButton action="#{bean1.goPage2(inputValue)}" 
      value="Go Page 2" /> 
    </h:form> 

    <!-- Sets the second flash param --> 
    <c:set target="#{flash}" property="param2" value="Myparam2" /> 

    <!-- Tries to retrieve both of the params. 
    Note none of them is displayed at the first page hit. 
    If page refreshed, the second param which has been already set 
    using c:set above, will be displayed --> 
    <p>Param1: #{flash['param']}</p> 
    <p>Param2: #{flash['param2']}</p> 
</h:body> 
</html> 

Bean2

@ManagedBean 
@ViewScoped 
public class Bean2 implements Serializable { 

    public String getParam() { 
     /** 
     * Takes the parameter from the flash context 
     */ 
     return (String) FacesContext.getCurrentInstance().getExternalContext() 
       .getFlash().get("param"); 
    } 

} 

page2.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core"> 
<h:head /> 
<!-- This page just displays the received params --> 
<h:body> 
    <!-- Different ways to retrieve the params from the flash scope --> 
    <p>Param1: #{bean2.param}</p> 
    <p>Param1: #{flash.param}</p> 
    <p>Param1: #{flash['param']}</p> 
    <p>Param2: #{flash['param2']}</p> 

    <!-- Keep the first param for next redirection --> 
    #{flash.keep.param} 

    <!-- Return to page1 and see how the first param is retained --> 
    <h:button outcome="page1?faces-redirect=true" value="return to 1" /> 
</h:body> 
</html> 

Vedi anche:

+1

+1 Per menzionare l'attuazione buggy, è confuso l'inferno fuori di me. – mabi

+0

Impostato su EL non ha fatto il trucco per me, ma invece, posso suggerire di inserirlo in un bean gestito: 'FacesContext.getCurrentInstance(). GetExternalContext(). GetFlash(). Keep (" oValue "); \t \t this.oValue = (ValueClass) FacesContext.getCurrentInstance() getExternalContext() GetFlash() ottenere ("oValue");... ' Si lavora per' GET'ting nuovamente la pagina, ma si rompe in qualche modo dopo una richiesta di ajax + 'GET'. – DanielK