Converters e CastException - Conceitos? [RESOLVIDO]

6 respostas
C

Olá Pessoal, estou precisando fazer um converter, aliás até já implementei um entretanto está dando uma exception.
O caso é que tenho um Enum com algumas opções e numa página JSF, o usuário escolhe uma opção, eu seto essa opção num tipo do mesmo Enum no Bean e lá efetuo uma busca (Lá preciso desse objeto lá no bean…não pode ser a String correspondente no JSF)

Segue o código do converter:

public class ConverterOperador implements Converter {

	@Override
	public Object getAsObject(FacesContext facesContext, 
			UIComponent uiComponent, 
			String param) {
		
		Operadores operador = null;
		
		try {
			Operadores [] lista = Operadores.values();
			
			for (int i = 0; i<lista.length ; i++){
				 if (Integer.parseInt(param) ==	 lista[i].getCodigo()){
		         operador = lista[i];			 			 
				 }
		    }
		} catch (Exception e) {
			throw  new ConverterException(e);
		}
		return operador;
	}

	@Override
	public String getAsString(FacesContext facesContext, 
			UIComponent uiComponent, 
			Object obj) {
		
		   String descricao = null;
			try {
				Operadores[] lista = Operadores.values();
				for (int i= 0; i<lista.length; i++){
					
					if (Integer.valueOf(lista[i].getCodigo()).equals(obj)) //Aqui o erro acontece			
					descricao = lista[i].getDescricao();
				}
			} catch (Exception e) {
				throw new ConverterException(e);
			}
			return descricao;	
		}
}

CastException do Enum para o Integer…eu tenho que pegar o SelectItem correspondente que o camarada selecionou na interface e converter para o enum. Eu não entendo pq nesse caso eu precisaria desse segundo método para retornar a String correspondente pois a princípio o único que ia me atender seria o primeiro método pois esse sim retornaria um objeto. Mas empaca nesse segundo método que ao meu ver nem seria chamado… Ou o converter executa os dois métodos em cada requisição? Alguém pode me explicar melhor essa questão de converters?

6 Respostas

gomesrod

Olá,

O JSF usa sim os dois métodos, um é o complemento do outro:

Ao receber um submit do usuario, o getAsObject converte de String (parâmetro enviado na requisição) para o objeto correspondente, que será usado no managed bean.

Na hora de montar a página de resposta é o contrário, vc tem um atributo do ManagedBean que é um objeto (no seu caso, do tipo Operador), e ele é convertido para String para renderizar no HTML.

Ou seja, um é a “ida” o outro é a “volta”.

O problema do seu código é que, apesarem de ser operações contrárias, você copiou a mesma implementação. Tente refazer o getAsString, pensando o seguinte: ele vai receber como parâmetro um objeto, e deve transformá-lo em String de tal forma que o getAsObject consiga tratar depois.

Boa sorte, e qq coisa é só perguntar.

C

mas GomesRod, então o que está errado seria a lógica do converter?
Pq o que estou tentando fazer seria pegar o item correspondente do SelectMenu na interface, pegar o código associado a ele no selectMenu, instanciar uma lista com todos os itens do meu Enum, comparar o escolhido na interface com a lista dos itens e uma vez encontrado a equivalência, ia pegar e atribuir a String do item de Enum correspondente a variável descrição.
Meu raciocínio tá errado?

gomesrod

No método getAsString existem dois erros principais:

  1. Ele não deveria retornar a descrição e sim o código. Lembre-se que a string retornada no getAsString deve ser a mesma utilizada pelo getAsObject, eles trabalham em par.

Assim:
getAsObject recebe o código e retorna o objeto enum.
getAsString recebe o objeto enum e retorna o código.

(obs: os dois também poderiam trabalhar com a descrição… tudo depende do projeto, o importante é que ambos os métodos entrem em um acordo. Estou supondo que o primeiro está correto, portanto o que vai ser usado é o código)

imagine o seguinte:

String f1 = "foo";
Object o = getAsObject(f1);
String f2 = getAsString(o);  // Deve ter o mesmo valor de f1

Bar b1 = new Bar();
String s = getAsString(b1);
Object b2 = getAsObject(s); // Deve ter o mesmo valor de b1

Uma é sempre a “volta” da outra… sacou? :slight_smile:

  1. Essa volta toda é desnecessária. Lembre-se que o parâmetro “obj” já contém o objeto enum. Basta fazer um cast…
C

Eu percebi…apanhei bastante mas consegui resolver. O primeiro método também tava dando pau… enfim mudei tudo.
Segue a solução se alguém se interessar:

public class ConverterOperador implements Converter {

	@Override
	public Object getAsObject(FacesContext facesContext, 
			UIComponent uiComponent, 
			String param) {
		
		Operadores operador = null;
		Operadores [] lista = Operadores.values();
		for (int i = 0; i<lista.length ; i++){
		 if (param.equals(lista[i].getDescricao())){
		         operador = lista[i];			 			 
			 }
		  }
	return operador;
	}

	@Override
	public String getAsString(FacesContext facesContext, 
			UIComponent uiComponent, 
			Object obj) {
		
		   String descricao = null;
		   Operadores[] lista = Operadores.values();
		   for (int i= 0; i<lista.length; i++){
		   if(lista[i].getCodigo()==(((Operadores)obj).getCodigo()))
		       descricao = lista[i].getDescricao();
				}
		return descricao;
		}
}

Confesso que ainda me confundo…acho que só a prática mesmo. Valew gomesrod.

gomesrod

Que bom que funcionou!

Só uma coisa… lembre-se que no getAsString você já tem o objeto no parâmetro obj.

Então por que não trocar isso:

public String getAsString(FacesContext facesContext, 
			UIComponent uiComponent, 
			Object obj) {
		
		   String descricao = null;
		   Operadores[] lista = Operadores.values();
		   for (int i= 0; i<lista.length; i++){
		   if(lista[i].getCodigo()==(((Operadores)obj).getCodigo()))
		       descricao = lista[i].getDescricao();
				}
		return descricao;
		}

por isso?

public String getAsString(FacesContext facesContext, 
         UIComponent uiComponent, 
         Object obj) {
                  Operadores ope = (Operadores)obj;
                  return ope.getDescricao();
}
C

legal…mas que estranho.
Eu não teria que percorrer a lista de itens do enum pra verificar a condição de igualdade do operador não?
Parece que ai já é direto…que estranho.

Criado 18 de julho de 2011
Ultima resposta 20 de jul. de 2011
Respostas 6
Participantes 2