Home > JavaEE, JSF > implicit navigation do JSF 2.0

implicit navigation do JSF 2.0

O JSF 2 teve o mecanismo de navegação melhorado. Agora além de regras de navegação implícitas foi adicionado um teste que pode ser feito usando a tag <if> dentro do <navigation-case>. E para finalizar a tag <to-view-id> aceita EL, o que torna tudo mais dinâmico.

Mas como são várias coisas, vamos por partes

Implicit Navigation

Agora quando retornamos um outcome na nossa action, caso nenhuma regra de navegação compatível seja encontrada, a navegação implícita entra em cena.

Vamos considerar os seguintes dados

from-view-id outcome to-view-id implícita
/pasta1/view1.xhtml view2 /pasta1/view2.xhtml
/pasta1/view1.xhtml /view2 /view2.xhtml
/pasta1/view1.xhtml /pasta2/view3 /pasta2/view3.xhtml
/pasta1/view1.xhtml view2.groovy /pasta1/view2.groovy
/pasta1/view1.xhtml /outrapasta/view2.groovy /outrapasta/view2.groovy



Acredito que a tabela seja auto explicativa, mas só para consolidar: caso o outcome devolvido comece com “/” será considerado como caminho absoluto, senão a view será procurada na mesma pasta da view que originou a action. Além disso se nenhuma extensão de arquivo for informada, será considerada a mesma extensão da view que originou a action.

E por fim, podemos definir o atributo “faces-redirect=true” para informar que queremos que seja usado um redirect, assim como faríamos com se tivéssemos definido nossa regra de navegação via xml, como por exemplo “meuOutcome?faces-redirect=true“.

Navigation case com <if>

Assim como as implicit navigation, o Seam também tem o <if> como o do JSF 2, porém no Seam esse <if> fica no pages.xml, um arquivo do Seam. Como sempre, vamos ver um exemplo para facilitar o entendimento.

@ManagedBean(name="pessoaBean")
@RequestScoped
public class PessoaBean{
 
	private EntityManager em; //injetado por algum mecanismo
 
	private Pessoa pessoa = new Pessoa();
 
	public void actionSalvar() {
		em.persist(pessoa);
	}
 
	//getters e setters suprimidos
}

agora vamos ver o faces-config.xml

...
<navigation-rule>
	<from-view-id>/cadastroPessoa.xhtml</from-view-id>
	<navigation-case>
		<if>#{pessoaBean.pessoa.id != null}</if>
		<to-view-id>/listagemPessoas.xhtml<to-view-id>
	</navigation-case>
</navigation-rule>
...

No nosso exemplo acima, mesmo sem retornar nenhum outcome, a navegação acontece da view “/cadastroPessoa.xhtml” para a view “/listagemPessoas.xhtml“, graças ao <if> do nosso <navigation-case>. Na expressão do exemplo usei algo bem simples, considerei que se o id da pessoa está diferente de nulo é porque a ação de salvar foi executada com sucesso. Obviamente podemos evoluir esse exemplo, mas como a finalidade aqui é didática acredito que seja sufucuente como está.

EL no <to-view-id>

Para finalizar vamos dar uma olhada no exemplo do uso da EL no <to-view-id>. Vamos ver esse outro exemplo.

@ManagedBean(name="cidadeBean")
@RequestScoped
public class CidadeBean{
 
	private EntityManager em; //injetado por algum mecanismo
 
	private Cidade cidade = new Cidade();
 
	private nextView;
 
	public String actionSalvar() {
		em.persist(cidade);
		nextView = "/listagemCidades.xhtml"
		return "sucesso";
	}
 
	//getters e setters suprimidos
}

E no faces-config.xml temos o seguinte

...
<navigation-rule>
	<from-view-id>/cadastroCidade.xhtml</from-view-id>
	<navigation-case>
		<from-outcome>sucesso</from-outcome>
		<to-view-id>#{cidadeBean.nextView}<to-view-id>
	</navigation-case>
</navigation-rule>
...

Com isso fechamos a parte de NavigationHandler do JSF 2. Na verdade ainda tem como novidade a possibilidade de consultarmos os NavigationCase’s de forma programática. Mas isso eu comento melhor quando for falar do que podemos fazer de forma programática no JSF 2 usando a implementação de referência, Mojarra (pois essas configurações programáticas que irei comentar não são especificadas).

Categories: JavaEE, JSF Tags: , ,
  1. May 19th, 2009 at 21:41 | #1

    Muito bom Gilliard.

    Acredito que o mais interessante nas opções explandas por você foi a primeira, implicit navigation. Assim é praticamente desnecessário escrever as regras de navegação no faces-config.xml.

    Excelente post. Você realmente está se tornando referência nacional quando se fala em JSF2.0 ((:

  2. May 20th, 2009 at 08:29 | #2

    Primeiramente muito obrigado Rafael :D

    Além do benefício da implicit navigation que você comentou, eu acho muito bom o if no navigation-case. Isso, junto com o suporte a passagem de parâmetros que virá no JEE 6, a gente vai poder programar sem ter aquela cara de managed bean que temos hoje.

    Vamos poder fazer com JSF como é possível fazer hoje no Seam, fazer binding da nossa view com os métodos de negócio, e então usando o if, avaliar como está o nosso modelo depois da ação e tomar uma decisão. É uma nova forma de pensar, e abre muitas possibilidades.

    Sem contar que a soma dessas três coisas que eu citei no artigo facilitam muito a adoção de convenções em vez de configurações (CoC) nas aplicações JSF.

  3. juniorsatanas
    August 27th, 2010 at 09:52 | #3

    Muito bom Post!

  4. Bruno Muniz
    June 10th, 2011 at 14:38 | #4

    Gilliard,

    Muito bom mesmo este post. Estes melhoramentos, nos facilitam ainda mais a nossa vida de programador.

    Valeu!

  5. Lucas
    July 6th, 2011 at 10:32 | #5

    Em primeiro lugar, parabéns pelo post e pelo blog. São conteúdos assim que nos ajudam a aprender e não nos deixam desistir.

    Segundo, Gilliard, estou tentando implementar um exemplo parecido com o seu, de um cadastro de Pessoa, utilizando o Netbeans + JSF 2.0 + PrimeFaces e sou novo no desenvolvimento web. Estou enfrentando o seguinte problema:

    Numa tela para inserir uma nova pessoa, ao utilizar o código:

    O Netbeans me informa: Propriedade “pessoa” desconhecida.

    Meu projeto está estruturado da seguinte forma:

    Classe Pessoa (com os getters e setters)
    PessoaDAO (com código SQL para cadastrar, alterar, remover…)
    PessoaBean.

    Espero continuar contando com sua ajuda… obrigado…

  6. Lucas
    July 6th, 2011 at 10:33 | #6

    Informando o código que não foi exibido na pergunta:

    inputText value=”#{pessoaBean.pessoa.nome}”

  7. July 6th, 2011 at 11:54 | #7

    oi @Lucas, primeiro obrigado.
    Sobre tua dúvida, você tem o getter do pessoa no PessoaBean?
    Você não tem esses códigos no github, codepase ou outro local onde seja mais fácil ver?

  1. May 27th, 2009 at 23:36 | #1