Dificuldades com Converters no VRaptor3

20 respostas
S

Oi pessoal, estou tentando fazer dois converters um que converta de Json para uma classe que estenda de Jsonable.class e outro que converta de um array de json para uma lista de classes que estende de Jsonable.class, mas nos dois casos o converter que esta “interceptando” é o que converte pra classe que estende de Jsonable.class.
Alguém poderia me dar uma luz na caca que estou fazendo, porque é sempre o mesmo converter que pega a requisição?

Segue abaixo partes dos códigos:

Converter da classe que estende de Jsonable.class

...
@Convert(Jsonable.class)  
public class JsonableConverter implements Converter<Jsonable> {
   public Jsonable convert(String value, Class<? extends Jsonable> type, ResourceBundle bundle) {  
	if (Strings.isNullOrEmpty(value)) {  
          return null;  
	}    
	...
   }
}

Chamada no Controller:

@Get @Path("/categoria")
	public void listaTudo(FiltroProcura FP) {
		List<Categoria> listacategoria = dao.getListaGeral(FP);
		 result.use(ExtJSJson.class).from(listacategoria).success(listacategoria != null).serialize();
	}

Converter que converte para uma Lista de Jsonable.class:

@Convert(List.class)  
public class ListJsonableConverter implements Converter<List<Jsonable>>{ 

	public List<Jsonable> convert(String value, Class<? extends List<Jsonable>> type, ResourceBundle bundle) {
			if (Strings.isNullOrEmpty(value)) {  
		      return null;  
			}  
			...
		}
}

Chamada do Controller:

@Get @Path("/categoriaLista")
	public void listaTudo(ArrayList<FiltroProcura> aFP) {
		List<Categoria> listacategoria = dao.getListaGeral(aFP);
		 result.use(ExtJSJson.class).from(listacategoria).success(listacategoria != null).serialize();
	}

Valeu Obrigado.

20 Respostas

Lucas_Cavalcanti

o converter de lista não vai funcionar, pq o cara que popula os parâmetros trabalha de um jeito diferente pra listas e arrays…

o que vc tá tentando fazer? pq você precisa do converter da lista?

S

Lucas Cavalcanti:
o converter de lista não vai funcionar, pq o cara que popula os parâmetros trabalha de um jeito diferente pra listas e arrays…

o que vc tá tentando fazer? pq você precisa do converter da lista?

Oi Lucas, de ante mão muito obrigado, cara, por enquanto eu só preciso disto pra receber uma lista de objetos que servirão pra fazer pesquisa no banco, tipo:
[{campo:“descricao”,operador:“TEXTO%”,tipo:“string”,valor:“sandro”},
{campo:“codigo”,operador:">=",tipo:“integer”,valor:10},
{campo:“codigo”,operador:"<=",tipo:“integer”,valor:20}]
talvez tenha mais campos em cada objeto JSON, estou tentando fazer bem abstrata pra funcionar pra “todos” os cadastros, no caso acima farei uma pesquisa do codigo 10 a 20 com todos que a descrição começe com sandro…
Em resumo é pra isto.

Valeu.

Lucas_Cavalcanti

teoricamente funciona mesmo sem o converter pra lista…

S

Não entendi.

Lucas_Cavalcanti

O VRaptor usa o conversor de Bolinha para converter a List.

mas isso pra quando você está usando parâmetros nomeados com algo como lista[0], lista[1], etc

no seu caso, como você está usando ExtJS, ele manda um json via parâmetro, certo?

o que você pode fazer é criar uma classe assim:

class Jsonables {
    List<Jsonable> jsonables;

   //getter e setter
}

receber essa classe no controller, e criar um converter pra ela.

Lucas_Cavalcanti

outra coisa que dá pra fazer é criar a classe:

class FiltrosProcura implements Jsonable {
     private List<FiltroProcura> filtros;
    //...
}

e modificar o json pra algo do tipo:

{"filtros": [{campo:"descricao",operador:"TEXTO%",tipo:"string",valor:"sandro"}, 
{campo:"codigo",operador:">=",tipo:"integer",valor:10}, 
{campo:"codigo",operador:"<=",tipo:"integer",valor:20}] }
S

Lucas Cavalcanti:
O VRaptor usa o conversor de Bolinha para converter a List.

mas isso pra quando você está usando parâmetros nomeados com algo como lista[0], lista[1], etc

no seu caso, como você está usando ExtJS, ele manda um json via parâmetro, certo?

o que você pode fazer é criar uma classe assim:

class Jsonables {
    List<Jsonable> jsonables;

   //getter e setter
}

receber essa classe no controller, e criar um converter pra ela.

já tinha visto um post seu que falava sobre esta solução, estava querendo fazer um converter pra List, mas se não dá acho que este será o caminho.

Valeu, mais uma vez Obrigado.

S

Lucas Cavalcanti:
outra coisa que dá pra fazer é criar a classe:

class FiltrosProcura implements Jsonable {
     private List<FiltroProcura> filtros;
    //...
}

e modificar o json pra algo do tipo:

{"filtros": [{campo:"descricao",operador:"TEXTO%",tipo:"string",valor:"sandro"}, {campo:"codigo",operador:">=",tipo:"integer",valor:10}, {campo:"codigo",operador:"<=",tipo:"integer",valor:20}] }

Mas neste caso teria que implementar uma lógica pra popular o List filtros no converter do Jsonable, e na maioria dos casos não terei/precisarei desta lista, acho que seria melhor criar um converter para uma outra classe que acho que é aquela sua primeira opção(class Jsonables {} ), correto?

Lucas_Cavalcanti

acho que vc não precisaria fazer nada mto diferente… como tá implementado o JSonableConverter? Vc tá convertendo na mão? ou está delegando pra alguma biblioteca?

S

xstream com JettisonMappedXmlDriver, faz quase todo o serviço :), não testei ainda com datas e outros tipos, mas pelo que vi funciona bem…

Lucas_Cavalcanti

então, é só vc mandar o XStream converter essa classe de FiltrosProcura, se eu não me engano o formato que eu falei consegue gerar uma instância já populada dessa classe.

S

fiz assim, notar comentário no código:

@Convert(Jsonables.class)    
public class JsonablesConverter implements Converter&lt;Jsonables&gt;{  
    public Jsonables convert(String value, Class&lt;? extends Jsonables&gt; type, ResourceBundle bundle) { 
		if (Strings.isNullOrEmpty(value)) {  
		  return null;  
		}  
		String json = "{\"list\":"+ value +"}";  
		XStream xstream = new XStream(new JettisonMappedXmlDriver());  
		xstream.alias("lista", Jsonables.class);  
		

		//Aqui eu queria fazer algo mais Genérico, pegar 
		//qualquer classe que estendesse de Jsonable, 
		//mas não vejo como  
		xstream.addImplicitCollection(Jsonables.class, "list", FiltroProcura.class); 
		

		return (Jsonables) xstream.fromXML("{\"lista\":" + json + "}");
	}
}

Se per pra melhorar sou todo ouvidos(digo olhos) :slight_smile:
Valeu, pela força.

Lucas_Cavalcanti

você não precisa ter o addImplicitCollection se você tiver:

class FiltrosProcura implements Jsonables {
    @XStreamImplicit
    private List<FiltroProcura> list;
}

só precisa dar um proccessAnnotations na classe

S

Lucas Cavalcanti:
você não precisa ter o addImplicitCollection se você tiver:

class FiltrosProcura implements Jsonables {
    @XStreamImplicit
    private List<FiltroProcura> list;
}

só precisa dar um proccessAnnotations na classe

Tentei usar e deu o seguinte erro:

The server encountered an internal error () that prevented it from fulfilling this request.

exception

com.thoughtworks.xstream.converters.ConversionException: campo : campo : campo : campo
---- Debugging information ----
message : campo : campo
cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message : campo : campo
class : br.com.aberta.tzion.util.Jsonables
required-type : java.util.ArrayList
path : /lista/list/campo
line number : -1
com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:89)
Lucas_Cavalcanti

tem um exemplo do json que vc tá mandando pra converter?

S

[{campo:“descricao”,operador:“TEXTO%”,tipo:“string”,valor:“sandro”},
{campo:“descricao”,operador:"%TEXTO",tipo:“string”,valor:“Mueller”}]

Lucas_Cavalcanti

só pra garantir, sem o @XStreamImplicit não funciona, né?

S

Funciona, mas ai tenho que colocar a linha abaixo no converter:

xstream.addImplicitCollection(Jsonables.class, "list", FiltroProcura.class);
Lucas_Cavalcanti

tenta preencher os atributos do @XStreamImplicit:

@XStreamImplicit(itemName="", wrapper="list")

ou algo do gênero… tem um desses que eu acho que funciona… no pior dos casos usa do jeito que vc falou mesmo.

S

Colocando parâmetros ele só aceitou assim: @XStreamImplicit(itemFieldName=“list”)
mas continuou dando dando o mesmo erro…

Valeu obrigado.

Criado 19 de dezembro de 2011
Ultima resposta 28 de dez. de 2011
Respostas 20
Participantes 2