Galera,
boa tarde! Seguinte, estou precisando renderizar um JSON usando VRaptor, mas a renderização em String tá cheia de nodes e alias indesejáveis.
Pesquisando com a equipe que trabalho, descobrimos que o VRaptor utiliza o motor JsonHierarchicalStreamDriver e XStream para renderização JSON. Primeira coisa, estamos corretos?
Nossa segunda dúvida é se há como integrar o GSon com o VRaptor reimplementando a classe XStreamJSONSerialization do VRaptor, não usando XStream mais, já que o GSon renderiza como precisamos.
Segue o nosso teste:
package br.com.mbs.hosting.test.json;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import br.com.mbs.hosting.service.AddressDTO;
import br.com.mbs.hosting.util.JSONResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
import com.thoughtworks.xstream.io.json.JsonWriter;
/**
* Testing the JSON rendering with GSon and VRaptor.
*
* @author Diego Martins, MBS Tecnologia - <a href="mailto:[email removido]">[email removido]</a>
* @version 1.0
* @date 25/05/2010 12:05:37
*/
public class JSONRenderComparision {
/**
* @param args
*/
public static void main( String[] args ) {
List< AddressDTO > pojosToRender = new ArrayList< AddressDTO >();
pojosToRender.add( new AddressDTO( "MG", "Uberlandia", "Brasil", 1L, 10L, "Afonso Pena", "38408-555", "", "", "1000", null ) );
pojosToRender.add( new AddressDTO( "MG", "Uberlandia", "Centro", 1L, 10L, "João Pinheiro", "38409-555", "", "", "2000", null ) );
pojosToRender.add( new AddressDTO( "MG", "Uberaba", "Centro", 5L, 85L, "Graham Bell", "38407-555", "", "", "3000", null ) );
// google
Gson gsonRender = new Gson();
System.out.println( "Google JSON render: \n" + gsonRender.toJson( pojosToRender ) );
// vraptor
XStream vraptorJSONRender = new XStream( new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter( Writer writer ) {
return new JsonWriter( writer, JsonWriter.DROP_ROOT_MODE ) {
@Override
public void addAttribute(String key, String value) {
if(!"class".equals(key)){
super.addAttribute(key, value);
}
}
};
}
} );
vraptorJSONRender.setMode( XStream.NO_REFERENCES );
vraptorJSONRender.alias( "root", AddressDTO.class );
System.out.println( "\n\nVRaptor JSON render: \n" + vraptorJSONRender.toXML( pojosToRender ) );
JSONResponse< List< AddressDTO > > testResponse = new JSONResponse< List< AddressDTO > >( "teste1", pojosToRender );
vraptorJSONRender = null;
vraptorJSONRender = new XStream( new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter( Writer writer ) {
return new JsonWriter( writer, JsonWriter.DROP_ROOT_MODE ) {
@Override
public void addAttribute(String key, String value) {
if(!"class".equals(key)){
super.addAttribute(key, value);
}
}
};
}
} );
//vraptorJSONRender.alias( "root", List.class );
System.out.println( "\n\nVRaptor JSONResponse (hosting) render: \n" + vraptorJSONRender.toXML( testResponse ) );
System.out.println( "\n\nGoogle JSON (JSONResponse) render: \n"
+ gsonRender.toJson( testResponse, new TypeToken< JSONResponse< List< AddressDTO > > >() {
}.getType() ) );
}
}
Sendo que JSONResponse é uma classe mais complexa para renderização de JSON. Segue abaixo:
package br.com.mbs.hosting.util;
public class JSONResponse<T> {
private String message;
private T data;
public JSONResponse(String message, T data) {
this.message = message;
this.data = data;
}
public String getMessage() {
return message;
}
public T getData() {
return data;
}
}
E a classe AddressDTO é um pojo com campos para representação de endereço. Segue:
package br.com.mbs.hosting.service;
import java.io.Serializable;
/**
* DTO for the Address entity. Copy from middleware-sin.
*
* @author Diego Martins, MBS Tecnologia - <a href="mailto:[email removido]">[email removido]</a>
* @version 1.0
* @date 20/05/2010 15:26:05
*/
public class AddressDTO implements Serializable {
private static final long serialVersionUID = -1438246671646795240L;
private Long id;
private Long idUf;
private Long idCity;
private Long idNeighborhood;
private Long idType;
private Long idTitle;
private String uf;
private String descUf;
private String city;
private String neighborhood = "";
private String type;
private String title;
private String address = "";
private String cep;
private Long idAddress;
private String addressComplementType;
private String addressComplement;
private String number;
private String typeDescription;
private String streetType;
public AddressDTO() {
}
public AddressDTO( String uf, String city, String neighborhood, Long idType, Long idTitle, String address, String cep,
String addressComplementType, String addressComplement, String number, StreetTypeDTO streetType ) {
super();
this.uf = uf;
this.city = city;
this.neighborhood = neighborhood;
this.idType = idType;
this.idTitle = idTitle;
this.address = address;
this.cep = cep;
this.addressComplementType = addressComplementType;
this.addressComplement = addressComplement;
this.number = number;
this.streetType = streetType;
}
// getters and setters.
}
O retorno do teste é:
Google JSON render: [{"idType":1,"idTitle":10,"uf":"MG","city":"Uberlandia","neighborhood":"Brasil","address":"Afonso Pena","cep":"38408-555","addressComplementType":"","addressComplement":"","number":"1000"},{"idType":1,"idTitle":10,"uf":"MG","city":"Uberlandia","neighborhood":"Centro","address":"João Pinheiro","cep":"38409-555","addressComplementType":"","addressComplement":"","number":"2000"},{"idType":5,"idTitle":85,"uf":"MG","city":"Uberaba","neighborhood":"Centro","address":"Graham Bell","cep":"38407-555","addressComplementType":"","addressComplement":"","number":"3000"}]VRaptor JSON render:
[
{
"idType": 1,
"idTitle": 10,
"uf": "MG",
"city": "Uberlandia",
"neighborhood": "Brasil",
"address": "Afonso Pena",
"cep": "38408-555",
"addressComplementType": "",
"addressComplement": "",
"number": "1000"
},
{
"idType": 1,
"idTitle": 10,
"uf": "MG",
"city": "Uberlandia",
"neighborhood": "Centro",
"address": "João Pinheiro",
"cep": "38409-555",
"addressComplementType": "",
"addressComplement": "",
"number": "2000"
},
{
"idType": 5,
"idTitle": 85,
"uf": "MG",
"city": "Uberaba",
"neighborhood": "Centro",
"address": "Graham Bell",
"cep": "38407-555",
"addressComplementType": "",
"addressComplement": "",
"number": "3000"
}
]VRaptor JSONResponse (hosting) render:
{
"message": "teste1",
"data": {
"br.com.azzu.hosting.service.AddressDTO": {
"idType": 1,
"idTitle": 10,
"uf": "MG",
"city": "Uberlandia",
"neighborhood": "Brasil",
"address": "Afonso Pena",
"cep": "38408-555",
"addressComplementType": "",
"addressComplement": "",
"number": "1000"
},
"br.com.azzu.hosting.service.AddressDTO": {
"idType": 1,
"idTitle": 10,
"uf": "MG",
"city": "Uberlandia",
"neighborhood": "Centro",
"address": "João Pinheiro",
"cep": "38409-555",
"addressComplementType": "",
"addressComplement": "",
"number": "2000"
},
"br.com.azzu.hosting.service.AddressDTO": {
"idType": 5,
"idTitle": 85,
"uf": "MG",
"city": "Uberaba",
"neighborhood": "Centro",
"address": "Graham Bell",
"cep": "38407-555",
"addressComplementType": "",
"addressComplement": "",
"number": "3000"
}
}
}Google JSON (JSONResponse) render:
{"message":"teste1","data":[{"idType":1,"idTitle":10,"uf":"MG","city":"Uberlandia","neighborhood":"Brasil","address":"Afonso Pena","cep":"38408-555","addressComplementType":"","addressComplement":"","number":"1000"},{"idType":1,"idTitle":10,"uf":"MG","city":"Uberlandia","neighborhood":"Centro","address":"João Pinheiro","cep":"38409-555","addressComplementType":"","addressComplement":"","number":"2000"},{"idType":5,"idTitle":85,"uf":"MG","city":"Uberaba","neighborhood":"Centro","address":"Graham Bell","cep":"38407-555","addressComplementType":"","addressComplement":"","number":"3000"}]}
Alguma idéia de como deixar a renderização do JSON do VRaptor igual a do GSon, mesmo que seja alterando métodos e parâmetros para os Writer, já olhamos as documentações existentes e chegamos num beco sem saída.
Ou senão há como integrar o GSon no VRaptor ou invés de usar o XStream?
Abraços e agradeço por atencedência.

