É só você criar uma classe que recebe a lista, a mensagem e o total:
publicclassListJsonWrapper{privateList<?>list;privateStringmsg;privatedoubletotal;publicListJsonWrapper(List<?>list;Stringmsg,doubletotal){// Passe para os atributos.}// Não há necessidade de getters e setters.}
Por isso eu queria personalizar o serializer json do VRaptor.
Rafael_Guerreiro
Para todos os jsons formatados você quer adicionar esse atributo? Cria um converter do XStream e anota ele com @Component e @ApplicationScoped…
joander.vieira
Exatamente !.
Mas como fazer esse converter ? me desculpe a ignorância, mas pode me enviar um exemplo.
Rafael_Guerreiro
:oops:
Não vai funcionar com converter, pois você precisa passar essas informações de algum jeito. Acho que a forma mais fácil de fazer isso é vc criando as seguintes classes:
publicclassMessage{privateStringmsg;privatedoubletotal;// Construtor e essas coisas}publicclassJsonWrapperextendsMessage{privateObjectobj;// Construtor e essas coisas}
Assim toda vez que você for mandar qualquer, vc usa o JsonWrapper. De alguma forma você tem que passar esses valores. Crie um Wrapper mais específico caso vc precise.
Eu uso esses wrappers, eles funcionam como converters também, assim eu consigo selecionar quais atributos de determinado objeto eu quero que vá para a requisição.
joander.vieira
Mas se eu usar com uma lista genérica não funciona os includes e excludes, ja tentei.
publicclassMessage{privateStringmsg;privatedoubletotal;// Construtor e essas coisas }publicclassJsonWrapperextendsMessage{privateList<Object>minhaLista;// Construtor e essas coisas }
Rafael_Guerreiro
Ai você usa o recursive().
Faça algo assim (exemplo real meu):
publicinterfaceDataTables{publicList<String>toListString(ResourceBundlebundle);}publicclassUserimplementsDataTables{// Atributos// aqui eu só transformo o que eu quero.@OverridepublicList<String>toListString(ResourceBundlebundle){List<String>list=newArrayList<String>();list.add(id.toString());list.add(name);list.add(bundle.getString(status.getLabel()));returnlist;}}publicclassDataTablesResult{@SuppressWarnings("unused")privateStringsEcho;privateList<List><String>>aaData=newArrayList<List><String>>();privatelongiTotalRecords=0;privatelongiTotalDisplayRecords=0;publicDataTablesResult(ResourceBundlebundle,StringsEcho,List<DataTables>list,longiTotalRecords,longiTotalDisplayRecords){this.sEcho=sEcho;this.setAaData(list,bundle);this.setiTotalRecords(iTotalRecords);this.setiTotalDisplayRecords(iTotalDisplayRecords);}@OverridepublicStringtoString(){return"{'iTotalRecords':"+iTotalRecords+", 'iTotalDisplayRecords':"+iTotalDisplayRecords+", 'aaData':"+aaData.toString()+"}";}@Overridepublicbooleanequals(Objectobj){if(obj==null)returnfalse;returnthis.hashCode()==obj.hashCode();}@OverridepublicinthashCode(){returnthis.toString().hashCode();}privatevoidsetAaData(List<DataTables>list,ResourceBundlebundle){if(list==null)list=newArrayList<DataTables>();for(DataTablesitem:list)this.aaData.add(item.toListString(bundle));}privatevoidsetiTotalRecords(longiTotalRecords){if(iTotalRecords>0)this.iTotalRecords=iTotalRecords;}privatevoidsetiTotalDisplayRecords(longiTotalDisplayRecords){if(iTotalDisplayRecords>0)this.iTotalDisplayRecords=iTotalDisplayRecords;}}// Uso dessa forma:@Get("/data/tables/{strategy}")publicvoidlist(DataTablesCriteriaBuilderstrategy,List<DataTablesFilter>filters,StringsEcho,intiDisplayStart,intiDisplayLength,List<Sort>sorts){try{if(strategy==null)thrownewIllegalArgumentException("The strategy cannot be null.");DataTablesResultdataTablesResult=this.buildResult(strategy,filters,sEcho,iDisplayStart,iDisplayLength,sorts);this.result.use(Results.json()).withoutRoot().from(dataTablesResult).recursive().serialize();}catch(Exceptione){this.logger.error("Unable to list this data tables.",e);this.result.use(Results.status()).badRequest("Unable to list this data tables.");}}privateDataTablesResultbuildResult(DataTablesCriteriaBuilderstrategy,List<DataTablesFilter>filters,StringsEcho,intiDisplayStart,intiDisplayLength,List<Sort>sorts){longiTotalRecords=dao.count(strategy);longiTotalDisplayRecords=dao.count(filters,strategy);List<DataTables>list=dao.list(filters,iDisplayStart,iDisplayLength,sorts,strategy);returnnewDataTablesResult(bundle,sEcho,list,iTotalRecords,iTotalDisplayRecords);}
Lucas_Cavalcanti
o jeito mais fácil de adicionar propriedades no json é criando uma classe wrapper mesmo… o xstream não te deixa fazer isso de um jeito fácil…
vc sempre pode usar uma biblioteca tipo Gson ou Jackson para gerar um JSON arbitrário, e escrever direto no response com:
result.use(Results.http()).body(oJson);
joander.vieira
Valeu pela ajuda de vocês só para deixar registrado segue a minha implementação com o Google GSON que funcionou muito bem.
public class AtributosExtraJson {
public int total;
public String msg;
public boolean success;
...
}
public interface IJsonUtil<T> {
public String toJson(JsonReturn<T> jsonReturn);
}
importjava.lang.reflect.Modifier;importjava.lang.reflect.Type;importorg.joda.time.DateTime;importcom.google.gson.Gson;importcom.google.gson.GsonBuilder;importcom.google.gson.JsonElement;importcom.google.gson.JsonPrimitive;importcom.google.gson.JsonSerializationContext;importcom.google.gson.JsonSerializer;publicclassJsonUtilImpl<T>implementsIJsonUtil<T>{@OverridepublicStringtoJson(JsonReturn<T>jsonReturn){//codigo opcional. Aqui estou definindo para nao serializar atributos com modificadores transiente e para serializar atributos nulosGsonBuildergsonBuilder=newGsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).serializeNulls();//codigo opcional. Aqui estou definindo um conversor para data no formato JodaTime.gsonBuilder.registerTypeAdapter(DateTime.class,newConvertJodaTimeToJson());// utilizar este codigo se tiver problema com referencia circular. Necessario incluir a classe GraphAdapterBuilder manualmente, ela nao vem o o Gson.//new GraphAdapterBuilder().addType(Usuario.class).registerOn(gsonBuilder);Gsongson=gsonBuilder.create();returngson.toJson(jsonReturn);}// Converter e formatar data no formato JodaTime para jsonprivateclassConvertJodaTimeToJsonimplementsJsonSerializer<DateTime>{@OverridepublicJsonElementserialize(DateTimesrc,TypetypeOfSrc,JsonSerializationContextcontext){returnnewJsonPrimitive(src.toString("dd/MM/yy"));}}}
JsonReturn<Pessoa>jsonReturn=newJsonReturn<Pessoa>();jsonReturn.setElementos(minhaListaDePessoa);jsonReturn.setMsg("Carregado com sucesso!.");jsonReturn.setSuccess(true);jsonReturn.setTotal(10);IJsonUtil<Pessoa>jsonUtil=newJsonUtilImpl<Pessoa>();response.setHeader("Content-Type","application/json");result.use(Results.http()).body(jsonUtil.toJson(jsonReturn));