[RESOLVIDO] Erro ao deserializar com Restfulie

10 respostas
R

Estou tentando pegar uma lista dos clientes com REST usando o Restfulie.

public class Teste 
{

	public static void main(String[] args) throws RestfulieException, IOException
	{
		RestClient restfulie = Restfulie.custom();
		restfulie.getMediaTypes().register(new XmlMediaType(){
			@Override
			protected void configure(XStream xstream)
			{
				xstream.processAnnotations(Cliente.class);
				xstream.processAnnotations(Vendedor.class);
				xstream.processAnnotations(Pedido.class);
			}
		}
		.withTypes(Cliente.class, Pedido.class, Vendedor.class));

		System.out.println( restfulie.at("http://localhost:8080/SyncOnline/clientes").accept("application/xml").as("application/xml").get().getResource() );
	}
	
}

Porém ele me retorna esse erro:

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: codigo : codigo : codigo : codigo ---- Debugging information ---- message : codigo : codigo cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException cause-message : codigo : codigo class : java.util.ArrayList required-type : java.util.ArrayList path : /list/codigo line number : -1

Vi vários erros semelhantes aqui no fórum, inclusive com Restfulie, mas com nenhum consegui resolver meu problema.

Se eu solicito essa URL pelo navegador obtenho o seguinte resultado:

{"list": [{"codigo": 1,"nome": "rafael","dataCriacao": {"@class": "sql-timestamp","$": "2011-12-22 10:13:18.0"},"ultimaAlteracao": {"@class": "sql-timestamp","$": "2011-12-22 10:13:18.0"}}]}

O que está errado?

10 Respostas

Lucas_Cavalcanti

não dá pra converter pra uma lista naturalmente, nem com json, nem com xml…

isso pq não tem como o XStream adivinhar quais são os tipos de elementos da lista…

o que vc pode fazer é o seguinte. Crie a classe:

@XStreamAlias("list")
class Clientes {
    @XStreamImplicit
    List<Cliente> cliente;
}

e colocar essa classe lá nos types. Daí ele vai converter pra um Clientes

R

Criei a classe:

@XStreamAlias("sincronizacoes")
public class Sincronizacoes 
{
	@XStreamImplicit
	private List<Cliente> clientes;
	
	@XStreamImplicit
	private List<Vendedor> vendedores;
	
	@XStreamImplicit
	private List<Pedido> pedidos;
	
	... getters setters
}

Funciona.
Mas, desse modo, com o @XStreamImplicit todas essas 3 listas ficam dentro de uma só. Ou seja, o primeiro registro pode ser um cliente o segundo um vendedor, ...

A saída ideal seria a seguinte:

<sincronizacoes>
  <clientes>
    <cliente>
      <nome>Rafael</nome>
    </cliente>
    <cliente>
      <nome>RafaelII</nome>
    </cliente>
  </clientes>
  <vendedores>
    <vendedor>
      <nome>Vendedor</nome>
    </vendedor>
  </vendedores>
</sincronizacoes>

Que quando deserializado teria o objeto igual que foi criado.

====

Deixa eu ver se entendi, o problema ocorre no unmarshall do XStream, porque ele não sabe qual tipo de lista é o nó e nem qual tipo de lista é o nó . Isso?
Não poderia criar um atributo no nó, informando isso?


...

R

Fazendo o teste sem o Restfulie, consigo fazer o processo de "ir e voltar" usando essa estrutura:

List<Cliente> clientes = new ArrayList<>();
		Cliente c = new Cliente();
		c.setNome("Rafael");
		clientes.add(c);
		
		c = new Cliente();
		c.setNome("RafaelII");
		clientes.add(c);
		
		List<Vendedor> vendedores = new ArrayList<>();
		Vendedor v = new Vendedor();
		v.setNome("Vendedor");
		vendedores.add(v);
		
		Sincronizacoes s = new Sincronizacoes();
		s.setClientes(clientes);
		s.setVendedores(vendedores);
		
		XStream x = new XStream();
		x.processAnnotations(Sincronizacoes.class);
		x.processAnnotations(Cliente.class);
		x.processAnnotations(Vendedor.class);
		x.processAnnotations(Pedido.class);
		
		String xml = x.toXML(s);
		
		Sincronizacoes s2 = (Sincronizacoes) x.fromXML(xml);
		System.out.println( s2.getVendedores().get(0).getNome() );

Não entendi o motivo do erro :roll:

Lucas_Cavalcanti

o que foi pra variável xml?

R

<sincronizacoes> <clientes> <cliente> <nome>Rafael</nome> </cliente> <cliente> <nome>RafaelII</nome> </cliente> </clientes> <vendedores> <vendedor> <nome>Vendedor</nome> </vendedor> </vendedores> </sincronizacoes>

Lucas_Cavalcanti

pode ser que o vRaptor não esteja processando as annotations…

tenta o seguinte:

crie uma classe que estende essa: https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/deserialization/XStreamXMLDeserializer.java

anote a classe com @Component, sobrescreva o método getConfiguredXStream, retornando o super mandando processar as anotações das classes que vc precisa

R

Tenho uma classe implementando o XStreamBuilder, não tem o mesmo resultado?

Lucas_Cavalcanti

mas ela tá mandando processar as anotações?

R

Agora está funcionando :roll:

Mas, não era exatamente o problema de processar anotações, porque fiz testes: processando as anotações, sem processar as anotações, mudando o tipo de retorno do result, … e em todos os testes, funcionou a serialização.

Não sei o que resolveu o problema. Vou fazer mais alguns testes amanhã para ver o que estava causando o problema.

Valeu a força!

renanreismartins

oi rafael, blz?

cara estou com um problema semelhante, mas eh na hora de enviar um objeto que contem uma lista.

http://www.guj.com.br/java/266742-erro-de-conversao-xstream---projeto-vraptor

ja passou por isso? abrass

Criado 22 de dezembro de 2011
Ultima resposta 2 de mar. de 2012
Respostas 10
Participantes 3