- javax.faces.context.FacesContext – Descrição
- javax.faces.context.Flash – Descrição
- Funcionalidades do Flash Scope
- Obter a instância de Flash Scope
- Atribuir uma informação ao Flash Scope
- Verificar se uma informação existe no Flash Scope
- Recuperar uma informação do Flash Scope
- Manter uma informação no Flash Scope para a próxima requisição
- finally{
Olá Pessoal, tudo bom?
O artigo de hoje está relacionado ao Flash Scope, ou um map de armazenamento de informações que pode ser utilizado para enviar informações entre requisições JSF. Veja na continuação desse artigo…
javax.faces.context.FacesContext – Descrição
O JSF define a classe FacesContext para representar toda a informação de contexto associada a uma nova request recebida e criação da resposta correspondente.
Uma instância da classe FacesContext é criada pela implementação do JSF, antes do processamento da request do ciclo de vida da aplicação, por meio de uma chamada para o método getFacesContext() da classe FacesContextFactory.
Quando o processamento do ciclo de vida da request for concluído, a implementação do JSF chamará o método release, que dá às implementações do JSF a oportunidade de liberar os recursos adquiridos, bem como fazer um pool e reciclar as instâncias de FacesContext em vez de criar novas para cada solicitação.
javax.faces.context.Flash – Descrição
Por que foi necessário falar sobre o FacesContext? Porque o Flash é um armazenamento temporário que está contido dentro de uma instância da classe FacesContext. E como descrito na seção anterior, o FacesContext é uma classe temporária que vive durante uma requisição, logo o armazenamento do Flash Scope está disponível apenas durante o ciclo de vida de um request.
Na prática a utilização mais comum do Flash Scope é para o envio de informações entre as requisições, principalmente entre páginas que utilizam managed beans diferentes, para que o mb destino possa recuperar alguma informação que estava presente no mb origem.
A classe Flash implementa a interface java.util.Map<String, Object>. Assim existem três pontos a serem destacados. O primeiro é que todos os métodos que um Map possui estão presentes aqui, dessa forma para atribuir e recuperar informações do Flash utilizamos os mesmos de um Map. O segundo é que a Key que armazena determinado objeto é do tipo String, e por fim qualquer objeto pode ser armazenado, porque o value é do tipo Object.
A explicação sobre a utilização do flash scope será apresenta com dois códigos, um para a parte dentro de classes Java e outro para páginas xhtml utilizando JSF expressions.
Funcionalidades do Flash Scope
Existem várias operações que podem ser realizadas no flash scope, mas esse artigo vai se concentrar em 5 pontos básicos:
- Obter a instância de Flash Scope
- Atribuir uma informação ao Flash Scope
- Verificar se uma informação existe no Flash Scope
- Recuperar uma informação do Flash Scope
- Manter uma informação no Flash Scope para a próxima requisição
Para os exemplos de código para classes Java será necessário realizar um import de duas classes, da classe FacesContext e da classe Flash, como mostra o código abaixo:
1 2 |
import javax.faces.context.FacesContext; import javax.faces.context.Flash; |
Obter a instância de Flash Scope
Para obter uma instância do Flash é necessário pegar a instância corrente de FacesContext e, a partir do seu contexto externo, obter a instância. Veja o código abaixo:
1 |
Flash flashScope = FacesContext.getCurrentInstance().getExternalContext().getFlash(); |
Já para obter a instância do flash scope nas páginas xhtml é muito simples. A JSF expression define uma expressão própria para o Flash, #{flash}. A utilização dessa expression traz a instância do flash scope da requisição atual a partir da instância de FacesContext.
1 |
#{flash} |
Atribuir uma informação ao Flash Scope
Como já descrito uma informação atribuída ao Flash Scope terá a duração de um único request. Para enviar uma informação ao Flash em uma classe Java deve ser utilizado o método put(String, Object). O código abaixo envia um enum para o Flash, com a key acaoUsuario:
1 |
flashScope.put("acaoUsuario", AcaoUsuarioEnum.INSERIR); |
Para atribuir um valor ao flash através de uma página xhtml, será necessário importar o name space JSTL Core
1 |
xmlns:c="http://java.sun.com/jsp/jstl/core" |
Além de utilizar a tag c:set para enviar as informações. O código abaixo envia a String aquiEhUmTeste com a key testeSet para o Flash:
1 |
<c:set target="#{flash}" property="testeSet" value="aquiEhUmTeste" /> |
Verificar se uma informação existe no Flash Scope
Para verificar se uma key está presente no Flash, deve ser utilizado o método boolean containsKey(String key), se retornar true existe uma key dentro do Flash do contrário o retorno será false.
1 |
boolean existeKey = flashScope.containsKey("acaoUsuario"); |
Desconheço a forma de fazer isso diretamente no xhtml.
Recuperar uma informação do Flash Scope
Para recuperar uma key do Flash, utilize o método Object get(String key). Após a chamada do método deverá ser realizado um cast para a classe desejada. Por exemplo, o código abaixo obtém uma AreaCientifica através do get para a key valorSelecionado:
1 |
this.areaCientifica = (AreaCientifica) flashScope.get("valorSelecionado"); |
Para obter um valor que se encontra no flash em uma página xhtml existem duas maneiras. Usar diretamente o ponto para acessar o nome da key desejada, ou colocar a key entre colchetes e aspas simples:
1 |
#{flash.acaoManterEnum} |
1 |
#{flash['acaoManterEnum']} |
Manter uma informação no Flash Scope para a próxima requisição
É possível manter um objeto presente no Flash para que ainda esteja presente na próxima requisição. Para isso, utilize o método void keep(String key). O objeto continuará presente no próximo ciclo de vida JSF. É muito importante frisar a duração de somente um request, se após isso o método keep não for chamado novamente o objeto armazenado não estará presente.
1 |
flashScope.keep("filtroPesquisa"); |
Por fim, para utilizar o keep em uma página xhtml, mantendo assim um valor para a próxima requisição, utilize o seguinte código:
1 |
#{flash.keep['filtroPesquisa']} |
finally{
O uso do flash scope é muito pequeno, pois somente quando queremos passar informações ao managed bean destino é que será utilizado. Normalmente se estamos no mesmo managed bean e para manter a informação armazenada neste basta utilizar a annotation@ViewScope
Duvidas ou sugestões? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!
Até um próximo post!
Renato Lopes says
Estou tentando utilizar flash, e estou tendo o seguinte erro:
Exception
javax.servlet.ServletException: javax/xml/bind/DatatypeConverter
javax.faces.webapp.FacesServlet.service(FacesServlet.java:683)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause
java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
com.sun.faces.util.ByteArrayGuardAESCTR.encrypt(ByteArrayGuardAESCTR.java:131)
com.sun.faces.context.flash.ELFlash$PreviousNextFlashInfoManager.encode(ELFlash.java:1489)
com.sun.faces.context.flash.ELFlash.doLastPhaseActions(ELFlash.java:745)
com.sun.faces.context.flash.ELFlash.doPostPhaseActions(ELFlash.java:669)
com.sun.faces.context.ExternalContextImpl.doLastPhaseActions(ExternalContextImpl.java:1276)
com.sun.faces.context.ExternalContextImpl.redirect(ExternalContextImpl.java:805)
com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:275)
com.sun.faces.application.NavigationHandlerImpl.handleNavigation(NavigationHandlerImpl.java:183)
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:132)
javax.faces.component.UICommand.broadcast(UICommand.java:330)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:870)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1418)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:201)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:670)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Mauda says
Olá Renato, tudo bom?
Não tenho uma certeza sobre o que está acontecendo, mas pode estar relacionado com a falta de uma biblioteca, pois na stack trace que foi informada existe a seguinte linha:
java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
Assim parece estar faltando a dependencia java.xml.bind.
Se vc estiver utilizando a JDK da 9 para cima, essa biblioteca foi depreciada.
De uma olhada nesse artigo da Caelum para verificar se existe alguma solução para vocë.
https://blog.caelum.com.br/erros-com-jaxb-no-java-9/
Obrigado!
Henriques says
Cara muito bom seu artigo precisava ler algo assim, encontro muitas referências antigas e tinhas minhas dúvidas quanto a sua utilização, poderia sanar duas duvidas:
1 – Saberia dizer se o armazenamento feito no Flash Scope está relacionado com o Flash do navegador (plugin Adobe)?
2 – é uma boa pratica o seu uso ainda? Pergunto, pois observei que se trata de um recurso antigo…
Obs.: Atualmente faço uso dele para passagem de parametros durante a navegação de algumas páginas…
Mauda says
Olá Henrique, tudo bom?
Obrigado pelo feedback! Isso significa muito pra mim!
1 – Não está relacionado. É uma área de memória do browser onde ele armazena.
2 – Na verdade o JSF está em desuso. Hoje em dia está sendo utilizado mais angular entre outras linguagens JavaScript da parte de Front end. Isso ajuda também aos designers pois eles podem trabalhar com o Html e css mais limpo que uma página JSF.
Precisando estamos por aqui!
Obrigado!
Henrique says
Obrigado pelo retorno Mauda.
Sobre a segunda dúvida, reconheço o crescimento do Angular em projetos JEE. Porém recebemos um sistema para manutenção em JSF com Java 7, mas não temos equipe especialistas na área. Enfim, estamos estudando as tecnologias envolvidas e o que há de melhor para um pequeno upgrade, vi o FlashScope como uma boa opção para um certo problema que estamos tendo.
Grato novamente.
Mauda says
Olá Henrique, tudo bem?
Perfeito então. Realmente ainda existem e existirão por muito tempo os sistemas legados.
Obrigado e duvidas estamos por aqui!