Entenda o escopo do Flash no JSF2

Pelo que entendi, os objects colocados dentro do escopo do Flash em um ciclo de vida de solicitação de faces estarão disponíveis para o ciclo de vida da próxima solicitação de faces e, em seguida, serão limpos.

Suponha que eu tenha duas páginas:

page01.xhtml :

   

Page01Bean:

 @ManagedBean @RequestScoped public class Page01Bean { public void action(){ FacesContext.getCurrentInstance().getExternalContext().getFlash().put("fooKey", "fooValue"); } } 

page02.xhtml :

  

Assim, quando o botão em page01.xhtml é clicado, um ciclo de vida de solicitação de faces (digamos, ciclo de vida A) é iniciado e define o valor para o flash sob a chave chamada fooKey

Então eu abro outra guia do navegador e navego page02.xhtml . Outro ciclo de vida de solicitação de faces (digamos, ciclo de vida B) começa a renderizar essa página. Eu esperava que o ciclo de vida B pudesse acessar o escopo de flash do ciclo de vida anterior (isto é, ciclo de vida A) e exibir fooValue na page02.xhtml . No entanto, não exibe nada.

Por favor, corrija-me o que eu entendi errado sobre o alcance do flash neste exemplo. Muito obrigado

   

Em suma, as variables ​​armazenadas no escopo do flash sobreviverão a um redirecionamento e serão descartadas posteriormente. Isso é realmente útil ao implementar um padrão Post-Redirect-Get.

Se você tentar navegar para outra página por redirecionamento e acessar os atributos no carregamento, eles estarão lá. Após essa solicitação, os valores no flash serão descartados. Por exemplo:

Você está em page1.xhtml e tem um commandLink que redireciona para uma nova página com um método como este (Observação: eu usarei navegação implícita).

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

Quando pageB.xhtml é processado, você pode acessar esses valores por expressões EL, como

  

que exibirá o “Hello World!” string que salvamos anteriormente em navigateToPageB.

Quanto à sua pergunta, ao abrir uma nova guia no seu explorador, você não está acessando o mesmo contexto que estava acessando na guia anterior, portanto, sua variável não estará disponível nela.

A resposta anterior está correta, mas só por completude eu gostaria de dizer que tem havido muitos problemas nas implementações de Mojarra com tudo isso, mas finalmente conseguiram fazer com que funcionasse corretamente nas versões Mojarra 2.1.27 e 2.2.5.

Como o @Gamb diz, o objective do escopo do flash é manter um parâmetro vivo mapeando-o internamente através do redirecionamento. Também podemos manter o parâmetro ativo por mais tempo, se precisarmos. Além da maneira mencionada, FacesContext#getCurrentInstance#getExternalContext#getFlash#put , há também a chance de definir o parâmetro via expressão EL, usando . Eu implementei um teste básico após o SSCCE, que mostra um leque mais amplo de opções, usando duas visões:

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

            

Param1: #{flash['param']}

Param2: #{flash['param2']}

Feijão2

 @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

      

Param1: #{bean2.param}

Param1: #{flash.param}

Param1: #{flash['param']}

Param2: #{flash['param2']}

#{flash.keep.param}

Veja também:

  • Documentação flash JSF
  • Mantendo os parâmetros de flash quando o usuário recarrega manualmente a vista