0
votes

Ne peut pas désérialiser l'objet JSON à l'aide de Desérialisateur personnalisé

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;
    }
}


4 commentaires

Quelle est la sortie que vous attendez?


@Deadpool pour 1), puisque j'ai fourni un constructeur pour propriété qui accepte list , je m'attendais à ce qu'il soit utilisé. Pour 2) Je m'attendais à créer une propriété où sa valeur est un objet de type ref


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 , juste ceux que j'ai mentionnés dans la question.


3 Réponses :


1
votes

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 ( référence code> est dépouillé de toutes les annotations Jackson)

Classe de propriété: P>

Template t = mapper.readValue(in, Template.class);


2 commentaires

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



3
votes

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");
    }
}


0 commentaires

0
votes

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);
  }
//...


0 commentaires