J'ai un fichier JSON comme celui-ci:
public class Property { private Object value; public Property(String value) { this.value = value; } public Property(int value) { this.value = value; } public Property(List<String> values) { this.value = values; } public Property(boolean value) { this.value = value; } public Property(Ref reference) { this.value = reference; } } public class Ref { private String reference; @JsonCreator public Ref(@JsonProperty("Ref") String reference) { this.reference = reference; } }
3 Réponses :
Voici ma solution, il utilise la réflexion Java pour correspondre au constructeur de propriétés vers le type de données JSON. Je devais modifier les constructeurs de propriétés un peu pour correspondre à la désérialisation de Jackson (utilisez des types d'enveloppement au lieu des primitives). En outre, le type de référence est construit à partir de la carte ( Classe de propriété: P> référence code> est dépouillé de toutes les annotations Jackson)
Template t = mapper.readValue(in, Template.class);
Merci pour la réponse! Utilise la réflexion la seule solution? Je crains que cela surcharge des choses.
Je ne pouvais pas obtenir à Jackson de bien désérialiser ref
Une approche valide consiste à écrire votre créateur personnalisé:
@JsonCreator public Property(JsonNode node) { switch (node.getNodeType()) { case STRING: value = node.asText(); break; case NUMBER: value = node.asInt(); break; case BOOLEAN: value = node.asBoolean(); break; case ARRAY: Iterator<JsonNode> elements = node.elements(); List<String> list = new ArrayList<>(); while (elements.hasNext()) { JsonNode element = elements.next(); if (element.isTextual()) { list.add(element.textValue()); } else { throw new RuntimeException("invalid data type"); } } value = list; break; case OBJECT: try { value = new ObjectMapper().treeToValue(node, Ref.class); } catch (JsonProcessingException e) { throw new RuntimeException("invalid data type", e); } break; default: throw new RuntimeException("invalid data type"); } }
Dans mon expérience Jackson n'aime pas l'interface de la liste entière.
public class Property{ //... public Property(String[] list){ this.value = Arrays.asList(list); } //...
Quelle est la sortie que vous attendez?
@Deadpool pour 1), puisque j'ai fourni un constructeur pour code> propriété code> qui accepte
list code>, je m'attendais à ce qu'il soit utilisé. Pour 2) Je m'attendais à créer une propriété où sa valeur code> est un objet de type
ref code>
Désolé, je n'ai pas vraiment votre question, je ne sais pas pourquoi vous avez plusieurs constructeurs remplaçant la même valeur de propriété avec différents types. En fait, vous avez juste besoin d'informations spécifiques de ce fichier JSON?
@Deadpool parce que chaque propriété
du JSON peut avoir différents types: chaîne, int, liste, etc., donc j'ai fourni un constructeur pour chaque type. Peut-être qu'il y a une meilleure façon de le faire, je ne sais pas. Je ne veux pas laisser n'importe quel type i>, juste ceux que j'ai mentionnés dans la question.