Dificuldades com Converters no VRaptor3

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.

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?

[quote=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?[/quote]

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.

teoricamente funciona mesmo sem o converter pra lista…

Não entendi.

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.

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}] }

[quote=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.[/quote]

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.

[quote=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}] } [/quote]

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?

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?

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

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.

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 = &quot;{\&quot;list\&quot;:&quot;+ value +&quot;}&quot;;  
		XStream xstream = new XStream(new JettisonMappedXmlDriver());  
		xstream.alias(&quot;lista&quot;, 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, &quot;list&quot;, FiltroProcura.class); 
		

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

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

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

[quote=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[/quote]

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)

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

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

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

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

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

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.