En utilisant Jackson JSON Generator, comment puis-je écrire plusieurs objets dans un seul champ?
Supposons que j'ai trois classes (getters et setters laissé de côté pour des raisons de concision):
@JsonAutoDetect
public class InfoCollection{
private InfoType1 info1;
private InfoType2 info2;
}
@JsonAutoDetect
public class InfoType1{
private String fieldA;
}
@JsonAutoDetect
public class InfoType2{
private String fieldB;
}
J'essaie d'écrire un JsonSerializer.serialize()
fonction qui sérialise un InfoCollection
objet dans ce format:
{
"allInfo":{
"fieldA":"foo",
"fieldB":"bar"
}
}
C'est ce que j'ai maintenant:
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("allInfo");
jsonGenerator.writeObject(myInfoCollection.getInfo1());
jsonGenerator.writeObject(myInfoCollection.getInfo2());
jsonGenerator.writeEndObject();
qui est à l'origine de l'exception suivante:
org.codehaus.jackson.JsonGenerationException: Can not start an object, expecting field name
Me manque un petit quelque chose ou suis-je totalement les choses à ce sujet dans le mauvais sens?
REMARQUE: UN couple de solutions proposées jusqu'à présent sont de l'écriture de chaque champ de InfoType1
et InfoType2
. Je suis à la recherche d'une solution qui ne nécessite pas de cela, parce que je voudrais utiliser la solution sur d'énormes classes avec de nombreux champs.
source d'informationauteur CFL_Jeff
Vous devez vous connecter pour publier un commentaire.
Au lieu de l'appeler
writeFieldName("allInfo")
vous devriez appelerwriteObjectFieldStart("allInfo")
parce que "allInfo" est un objet JSON. Si votre personnalisé sérialiseur devrait regarder la façon suivante:Ou vous pouvez essayer d'annotation de l'approche fondée sur:
(Vous devez activer
SerializationConfig.Feature.WRAP_ROOT_VALUE
fonction dans l'ordre pour que cela fonctionne. Voir La sérialisation caractéristiques)Dans l'avenir, lorsque vous avez une trace de la pile, faites-nous savoir dans la ligne à laquelle le problème s'affiche.
Cela dit, la solution est probablement:
Solution à l'aide d'un objet wrapper:
Qui fait que Jackson ne voir que ce que vous voulez et comment vous voulez.
Vous pouvez également utiliser la réflexion pour recueillir de manière récursive tous les champs et leurs noms:
collectFields
devrait examiner tous les domaines et ajoutez le tout à la liste qui est soit primitif ou, disons, oùfield.getType().getName().startsWith("java.lang")
ou toutes autres règles dont vous avez besoin.Si le champ est un champ de référence, appel
collectFields()
de manière récursive.Lorsque vous avez la liste, il suffit d'appeler
jsonGenerator
dans une boucle pour écrire les résultats.