Порядок свойств Джексона, основанный на значении поля - PullRequest
1 голос
/ 12 марта 2019

Я пытаюсь сериализовать и десериализовать класс Java, используя Jackson, а JsonPropertyOrder зависит от значения поля version в классе. Если version = 1, я хочу, чтобы заказ был {"start1", "start2"}, если version = 2, заказ должен быть {"end1", "end2"}.
У меня ниже класса:

 @Builder
 @Value
 @AllArgsConstructor(onConstructor=@__(@JsonCreator))
 @JsonPropertyOrder(custom property order depending on version field)
 public class ClassA {

   @NonNull Integer version;

   @NonNull String start1;

   @NonNull String start2;

   @NonNull String end1;

   @NonNull String end2;
}

Как определить JsonPropertyOrder в зависимости от версии во время выполнения. Если мне нужно использовать пользовательский Deserializer, я не могу понять, как именно он должен быть реализован и установлен с помощью ObjectMapper.

Это код для десериализации:

private final ObjectMapper objectMapper = new ObjectMapper();//have initialzed this as a bean
String jsonStr = "{\"version\":1, \"startLat\":\"47.6812\", \"startLng\":\"-122.3268\", \"endLat\":\"47.6074\", \"endLng\":\"-122.3377\"}";
ClassA objA = null;
    try {
        objA = objectMapper.readValue(jsonStr, ClassA.class);
    } catch (IOException e) {
        log.error("Error deserializing the string", jsonStr, e);
    }
return objA;

** РЕДАКТИРОВАТЬ: я пропустил имп части. Порядок свойств здесь имеет значение, потому что сериализованная строка может не иметь имен полей. Это возможно сделать? Таким образом, str [1, "47.6812", "-122.3268"] нужно будет десериализовать до версии полей, start1, start2.

1 Ответ

0 голосов
/ 12 марта 2019

Если эти свойства являются эксклюзивными, почему бы не создать более краткий POJO, удалив два из них?Вы можете использовать знание, что 1 означает что-то отличное от 2, введя некоторые isMethod -es или Enum.Для сериализации класса как JSON array необходимо использовать аннотацию @JsonFormat(shape = JsonFormat.Shape.ARRAY).Для десериализации вы можете использовать конструктор 3-arg с аннотациями @JsonCreator и @JsonProperty.Свойства final.Все вместе делает - класс хорошо реализован.См. Пример:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Objects;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();

        ClassA classA1 = new ClassA(1, "Start_1", "Start_2");
        ClassA classA2 = new ClassA(2, "End_1", "End_2");

        String json1 = mapper.writeValueAsString(classA1);
        String json2 = mapper.writeValueAsString(classA2);

        System.out.println(json1);
        System.out.println(json2);

        System.out.println(mapper.readValue(json1, ClassA.class));
        System.out.println(mapper.readValue(json2, ClassA.class));
    }
}

@JsonFormat(shape = JsonFormat.Shape.ARRAY)
class ClassA {

    private final Integer version;

    private final String value1;
    private final String value2;

    @JsonCreator
    public ClassA(@JsonProperty("version") Integer version,
                  @JsonProperty("start1") String value1,
                  @JsonProperty("start2") String value2) {
        Objects.requireNonNull(version);
        if (!(version == 1 || version == 2)) {
            throw new IllegalArgumentException("Version is not supported!");
        }
        this.version = version;
        this.value1 = value1;
        this.value2 = value2;
    }

    @JsonIgnore
    public boolean isStart() {
        return version == 1;
    }

    @JsonIgnore
    public boolean isEnd() {
        return version == 2;
    }

    public Integer getVersion() {
        return version;
    }

    public String getValue1() {
        return value1;
    }

    public String getValue2() {
        return value2;
    }

    @Override
    public String toString() {
        return "ClassA{" +
                "version=" + version +
                ", value1='" + value1 + '\'' +
                ", value2='" + value2 + '\'' +
                ", isEnd()='" + isEnd() + '\'' +
                ", isStart()='" + isStart() + '\'' +
                '}';
    }
}

Над печатью кода:

[1,"Start_1","Start_2"]
[2,"End_1","End_2"]
ClassA{version=1, value1='Start_1', value2='Start_2', isEnd()='false', isStart()='true'}
ClassA{version=2, value1='End_1', value2='End_2', isEnd()='true', isStart()='false'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...