Vraptor json include

6 respostas
biggahed

Oi pessoal, primeiro post por aqui.
Estou começando no vraptor e esbarrei numa exception que nao estou conseguindo resolver.

No meu controller eu tenho

result.use(json()).from(
                new Success(true)
                    .with("ativo", obj.getAtivo()?"ativo":"inativo")
                    .message("Valores gravados com sucesso")
                ).include( "messages","attrs")
                .serialize();

e tambem

public class Success {
    private final boolean success;
    private final Map<String,String> attrs;
    private final List<Message> messages;

    public Success(boolean success) {
        this.success = success;
        this.messages = new ArrayList<Message>();
        this.attrs = new HashMap<String, String>();
    }

    public Success message(String message) {
        messages.add(new ValidationMessage(message,""));
        return this;
    }

    public Success messages(List<Message> messages) {
        if(messages != null) {
            this.messages.addAll(messages);
        }
        return this;
    }

    public Success with(String key, String value) {
        this.attrs.put(key, value);
        return this;
    }
}

Que está causando a seguinte exception

Caused by: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class

at br.com.caelum.vraptor.serialization.xstream.XStreamSerializer.getActualType(XStreamSerializer.java:179)

at br.com.caelum.vraptor.serialization.xstream.XStreamSerializer.include(XStreamSerializer.java:158)

at br.com.etet.controller.Clsd.toggleStatus(Clsd.java:70)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57) 66 more

Estou usando o vraptor-3.1.2-20100310.010227-4

Se alguem souber me dizer do que se trata, serei muito grato :slight_smile:

6 Respostas

Lucas_Cavalcanti

é um bug do vraptor… estou investigando, já te passo um snapshot funcionando =)

Lucas_Cavalcanti

De qualquer forma, o VRaptor usa o XStream pra serializar os objetos, e o jeito que ele serializa Maps é algo do tipo:

<success>
  <attrs>
    <entry>
      <string>ativo</string>
      <string>ativo</string>
    </entry>
  </attrs>
</success>

pra fazer de outro jeito, você teria que configurar o XStream na mão… como vc gostaria que aparecessem os atributos?

Lucas_Cavalcanti

snapshot com esse bug corrigido:

http://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.1.2-SNAPSHOT/vraptor-3.1.2-20100316.002125-5.jar

biggahed

Opa, obrigado por responder tao rapido.
Eu fiz um teste aqui assim e nao ta mais dando erro.

result.use(json()).from(
                new Success(true)
                    .with("teste1","valor1")
                    .with("teste2","valor2")
                ).include( "messages","attrs")
                .serialize();

E obtive

{"success": {
  "success": true,
  "attrs": [
    [
      "teste1",
      "valor1"
    ],
    [
      "teste2",
      "valor2"
    ]
  ],
  "messages": [
  ]
}}

O que é usavel, mas nao é o que eu esperava. Quando eu fiz eu pensei que ele fosse me retornar algo assim

{"success": 
    {"success": true, 
       "attrs":{"teste1":"valor1",
                   "teste2":"valor2"},
       "messages": [] 
    }
}

É possivel fazer isso com o xtream? Se ele realmente gera esse xml que voce deu como exemplo acho que teria que fazer ele gerar algo do tipo

<success>
  <attrs>
    <entry>
      <teste1>valor1</teste1>
    </entry>
    <entry>
      <teste2>valor2</teste2>
    </entry>
  </attrs>
</success>

Tem ideia de como fazer isso?

Lucas_Cavalcanti

tanto pra xml qto pra json vc vai ter que criar um converter (do XStream) de maps…

Para isso vc precisa criar a classe:

@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {
   //delegate constructor

  @Override
  public XStream getXStream() {
       XStream xstream = super.getXStream();
       xstream.registerConverter(new MeuMapConverter());
       return xstream;
  }
}

onde esse MeuMapConverter() é uma classe que implementa com.thougthworks.xstream.converter.Converter e imprime o mapa do jeito que vc quer…
vc pode seguir esse tutorial: http://xstream.codehaus.org/converter-tutorial.html

biggahed

Brigadao cara, funcionou perfeitamente.

Criado 15 de março de 2010
Ultima resposta 17 de mar. de 2010
Respostas 6
Participantes 2