Tutorial JSF 2.0 – Criando um converter

Olá a todos.

Seguindo os tutoriais de JSF 2.0, vou criar um exemplo simples de como podemos criar um converter utilizando o JSF 2.0 e suas annotations. Você pode acompanhar os posts anteriores que ensinam como criar uma aplicação JSF e como funcionam os ManagedBean neste link.

Se você quer saber como criar um converter utilizando o JSF 1.2, veja este post.

Converter

Converter é o componente do JSF que é responsável por fazer a conversão de um objeto para uma String e de uma String para um objeto.

Ele atua entre a página JSF e o Managed Bean, convertendo textos da página automaticamente em objetos no Managed Bean. Desta forma, nós definimos como a conversão deve ocorrer e depois disso, trabalhamos como se estivéssemos acessando o próprio objeto na página JSF.

Esta abordagem é especialmente útil quando temos um objeto que possui uma conversão padrão. Logo, podemos implementar no componente como esta conversão ocorre, e apenas reutilizá-la. Trabalhamos mais orientado a objetos também, sem precisar acessar o conteúdo do objeto o tempo inteiro na hora de construí-lo.

Então vamos ao exemplo. Neste, criaremos um converter para estado. Vale notar que iremos inicializar os estados via código, mas nada impede de carregar estas informações do banco.

Vamos então ao nosso POJO, a classe State que representa o nosso estado:


public class State {

	private String name;
	private String uf;

	public State(String name, String uf) {
		super();
		this.name = name;
		this.uf = uf;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getUf() {
		return uf;
	}
	public void setUf(String uf) {
		this.uf = uf;
	}

	@Override
	public String toString() {
		return uf + " - " + name;
	}
}

A classe State não tem mistério, ela possui apenas os campos uf e name. Estes vão representar nosso Estado. A ideia é trabalhar com o atributo uf na página e receber o objeto State correspondente pronto no ManagedBean.

Vamos agora criar nossa classe converter, esta responsável pela conversão:

import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(value="stateConverter", forClass=State.class)
public class StateConverter implements Converter {

	private static Map<String, State> states = new HashMap<String, State>();

	static {
		states.put("RS", new State("Rio Grande do Sul", "RS"));
		states.put("SP", new State("São Paulo", "SP"));
		states.put("RJ", new State("Rio de Janeiro", "RJ"));
	}

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		System.out.println("Converter1");
		return states.get(arg2);
	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		System.out.println("Converter2");
		return ((State) arg2).getUf();
	}

	public static Map<String, State> getStates() {
		return states;
	}
}

Esta classe representa um converter do JSF. A grande novidade aqui é a annotation @FacesConverter. Mas vamos explicar passo a passo esta classe:

A interface Converter possui 2 métodos. Os nomes são auto explicativos. Um converte um atributo String em um Object e o seu nome é getAsObject. Já o outro método é o contrário, converte um Object em uma String e se chama getAsString. Estes métodos são o “core” da funcionalidade. Nestes 2 métodos vamos dizer como nosso objeto do ManagedBean sera convertido em uma String (getAsString) e também o caminho inverso, onde dizemos como converter uma String em um objeto (getAsObject). Na prática, definimos, como ele será enviado para a tela como string e como ele será construído novamente para  um Object no ManagedBean.

Vale ressaltar também a criação de um mapa contendo alguns estados. Para o nosso exemplo foram criados apenas 3 estados.

A annotation FacesConverter é a grande novidade nesta versão. O atributo value é um identificador que o converter terá dentro de nossa aplicação JSF, é a forma como vamos chamá-lo nas páginas. O atributo forClass indica para qual classe o seu converter realizará a conversão.

ManagedBean

Vamos ver como isso funciona na prática. Primeiro vamos criar nosso ManagedBean. Ele sera um ManagedBean normal do JSF 2.0 e terá um atributo state que será inicializado como São Paulo, SP.

import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean(name="stateMBean")
@RequestScoped
public class StateManageBean {

	private State state = new State("São Paulo", "SP");

	public String teste() {
		System.out.println(state);
		return "";
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

}

Repare que temos um método action chamado teste, que chamaremos para imprimir qual foi o state que recebemos no ManagedBean.

Abaixo, temos a nossa página JSF, ela é basicamente um campo de texto e um botão. Note que no campo de texto, atribuímos a value o objeto state diretamente e não o famoso stateMBean.state.uf , ou seja, estamos acessando o objeto state diretamente através do Input Text. O atributo de converter nós atribuímos o valor que identificamos na annotation FacesConverter.

<f:view>
	<h:form>
		<h:inputText value="#{stateMBean.state}" converter="stateConverter" />
		<h:commandButton value="teste" action="#{stateMBean.teste}" />
	</h:form>
</f:view>

O que ocorre agora? Vamos testar, na primeira requisição, nosso ManagedBean é criado e o valor default para ele, é SP. Logo você deve receber este valor no input text.

Isso ocorre porque dentro do converter, no método getAsString estamos retornando a UF quando recebemos um objeto State. Se mudarmos lá para recebermos o nome, automaticamente o retorno muda.

Experimente utilizar um estado do nosso universo conhecido (3 estados), por exemplo, Coloque RS e verifique que o ao executar a action teste, o objeto state impresso não é mais o SP e sim RS.

E como isso aconteceu?

Novamente, foi coverter, ao executar o método getAsObject.

Este exemplo é bem simples, mas nos ajuda a entender o mecanismo do converter, qualquer dúvida postem nos comentários.

Um abraço.

Tutorial JSF 2.0 – Actions e Navigation Rules

Este post foi movido para meu novo blog neste link.

Tutorial JSF 2.0 – Criando e Utilizando ManagedBean

Este post foi movido para meu novo blog.

Tutorial JSF 2.0 – Criando a aplicação

Este tutorial foi movido para meu novo blog neste link.

Injeção de dependência do Spring em Converter do JSF

Este tutorial foi movido para um novo endereço.

novo link.

Criando converter no jsf

Este post foi movido para este link do meu novo blog.