ago 03

Conversor em JSF2 com Servlet 3.0

Neste post falarei de como criar um converter para uma classe do meu modelo e também como utilizá-lo com um componente selectOneMenu.

Primeiramente, precisamos sobrescrever o método equals lá do nosso bean ( ex: MeuBean.java) para o qual será feito o converter.  Caso eu o identifique por um atributo específico, por exempo um id, o nosso equals ficaria da seguinte maneira:

 
        @Override
        public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Conta other = (Conta) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

Em seguida criamos uma nova classe chamada meuBeanConverter que irá implementar a interface Converter do pacote  javax.faces.convert , vamos anotá-la com a seguinte annotation: @FacesConverter, setando o atributo forClass da anotação com a nossa classe MeuBean.class .

Essa interface Converter possui 2 métodos que precisamos implementar:

  1. public Object getAsObject(FacesContext arg0, UIComponent arg1, String texto)
  2. public String getAsString(FacesContext arg0, UIComponent arg1, Object obj)

Onde o primeiro será acessado na fase do jsf : apply request values, quando o formulário for submitado, convertendo o atributo value  da tag option do html no objeto correspondente da nossa classe MeuBean. E o segundo no caminho inverso, quando queremos a partir de um objeto da nossa classe MeuBean,  mostrar no selectBox html o nosso objeto.

 
@FacesConverter(forClass = MeuBean.class)
public class ContaConverter implements Converter {

	@Override
	public Object getAsObject(FacesContext arg0, UIComponent arg1, String texto) {
		if (texto == null || texto.equals("")) {
			return null;
		}

		Long longId = Integer.valueOf(texto).longValue();
		MeuBean bean = //alguma maneira de recuperar o bean pelo atributo id
		return bean;

	}

	@Override
	public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) {
		// TODO Auto-generated method stub
		if (obj == null || obj.toString().equals("")) {
			return "";
		}
		return ((MeuBean) obj).getId().toString();
	}

}

Por fim no nosso html teremos no value do h:selectOneMenu  a propriedade que receberá o valor escolhido que será convertido para um objeto da classe MeuBean, e na listagem de f:selectItems uma lista de objetos MeuBean ( Ex: List<MeuBean> meusBeans ).

<h:selectOneMenu id="meuBean" value="#{meuMB.meuBean}">
	<f:selectItems value="#{meuMB.meusBeans}" ></f:selectItems>
</h:selectOneMenu>

Apenas um detalhe a mais, não setando o atributo itemLabel do f:selectItems, será necessário sobrescrever o toString do MeuBean, caso contrário será impresso a representação do objeto.