Как Джексон справляется с конфликтом карт? - PullRequest
1 голос
/ 16 апреля 2020

У меня есть следующий класс со свойством "ключ", которое сопоставляется с 2 различными JSON полями

public class A {

    @JsonAlias("Key")
    private String key;

    @JsonProperty("NewKey")
    private void unpackNewKey(Map<String, String> NewKey) {
        key = NewKey.get("value");
    }
}

Вот дескрипция JSON.

{
    "NewKey": {
        "value": "newkey",
    },
    "Key": "key"
}

Если я десериализую выше json до A.class

ObjectMapper mapper = new ObjectMapper();
A a = mapper.readValue(json, A.class)

Какое значение будет иметь a.key? это будет newkey или key? Пытаюсь понять, как Джексон справляется с конфликтом. Могу ли я указать порядок? например, если я хочу, чтобы key всегда отображался на NewKey, если в json существуют и Key, и NewKey, что мне делать?

1 Ответ

0 голосов
/ 17 апреля 2020

В вашем примере, где вы используете @JsonAlias("Key") и @JsonProperty("NewKey"), порядок зависит от порядка key-value пар в JSON полезной нагрузке. Если вы хотите всегда десериализовать с приоритетом ключа NewKey, вам нужно реализовать это в пользовательском JSON Deserialiser или в конструкторе. Простой пример, который вы можете найти ниже:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.readValue("{}", A.class));
        System.out.println(mapper.readValue("{\"Key\": \"key\"}", A.class));
        System.out.println(mapper.readValue("{\"NewKey\": {\"value\": \"newkey\"}}", A.class));
        System.out.println(mapper.readValue("{\"Key\": \"key\", \"NewKey\": {\"value\": \"newkey\"}}", A.class));
        System.out.println(mapper.readValue("{\"NewKey\": {\"value\": \"newkey\"}, \"Key\": \"key\"}", A.class));
    }
}

class A {

    private String key;

    @JsonCreator
    public A(Map<String, Object> json) {
        final String key = Objects.toString(json.get("Key"), null);
        final Map newKey = (Map) json.getOrDefault("NewKey", Collections.emptyMap());
        this.key = Objects.toString(newKey.get("value"), key);
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    @Override
    public String toString() {
        return key;
    }
}

Над отпечатками кода:

null
key
newkey
newkey
newkey
...