Заставить свойство сериализовать в идентичность в Джексоне - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть класс с

(отказ от ответственности, я пишу на Kotlin, но я перевожу его на Java, чтобы больше людей могли его читать)

@JsonIdentityInfo(
    ObjectIdGenerators.PropertyGenerator.class,
    "id"
)
public class Foo implements Serializable {
    public int id;
    public List<Foo> fooList;
}

Я хочу сериализовать другойобъект, который содержит список Foo s, но я хочу, чтобы все записи в сериализованном fooList были идентификаторами, а не объектами.Одно решение, которое пришло на ум, состояло в том, чтобы отсортировать их топологически в обратном порядке перед сериализацией, поскольку они формируют направленный ациклический граф.Но это, очевидно, не идеальное решение, поэтому мне интересно, есть ли аннотация или иным образом чистый способ Джексона сделать что-то подобное.

РЕДАКТИРОВАТЬ:
Класс, который содержит список Foo выглядитthis:

public class Bar implements Serializable {
    public List<Foo> fooList;
}

И когда я десериализирую экземпляр Bar из этого JSON:

{
  "fooList": [
    {
      "id": 0,
      "fooList": [1]
    }, 
    {
      "id": 1,
      "fooList": []
    }
  ]
}

И затем я сериализирую его обратно, я хочу, чтобы выходные данные были такими же, каквход, но вместо этого это:

{
  "fooList": [
    {
      "id": 0,
      "fooList": [
        {
          "id": 1,
          "fooList": []
        }
      ]
    },
    1
  ]
}

1 Ответ

0 голосов
/ 19 сентября 2018

Вы можете создать класс, который расширяется от класса Foo, чтобы предложить альтернативную сериализацию для fooList, используя аннотацию @JsonGetter, как обертку.

Foo class:

public class Foo implements Serializable {
    private int id;
    private List<Foo> fooList;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public List<Foo> getFooList() {
        return fooList;
    }

    public void setFooList(List<Foo> fooList) {
        this.fooList = fooList;
    }
}

Bar class:

public class Bar implements Serializable {
    public List<FooJsonSimplifiedSerializationWrapper> fooList;

    public List<FooJsonSimplifiedSerializationWrapper> getFooList() {
        return fooList;
    }

    public void setFooList(List<FooJsonSimplifiedSerializationWrapper> fooList) {
        this.fooList = fooList;
    }
}

FooFooJsonSimplifiedSerializationWrapper - это оболочка Foo для сериализации, и у нее есть метод для преобразования из Lst<Foo> в List <<code>FooFooJsonSimplifiedSerializationWrapper>, который выперед сериализацией придется позвонить в какой-то момент:

public class FooJsonSimplifiedSerializationWrapper extends Foo {
    @JsonGetter("fooList")
    public List<Integer> serializeFooList() {
        return this.getFooList().stream().map(f -> f.getId()).collect(Collectors.toList());
    }

    public static List<FooJsonSimplifiedSerializationWrapper> convertFromFoo(List<Foo> fooList) {
        return fooList.stream().map(f -> {
            FooJsonSimplifiedSerializationWrapper fooSimplified = new FooJsonSimplifiedSerializationWrapper();
            BeanUtils.copyProperties(f, fooSimplified);

            return fooSimplified;

        }).collect(Collectors.toList());
    }
}

Main с некоторыми тестами:

public static void main(String[] args) throws IOException {
    Foo foo = new Foo();
    foo.setId(1);

    Foo fooChild = new Foo();
    fooChild.setId(2);
    fooChild.setFooList(new ArrayList<>());

    Foo fooChild2 = new Foo();
    fooChild2.setId(3);
    fooChild2.setFooList(new ArrayList<>());

    foo.setFooList(Arrays.asList(fooChild, fooChild2));

    Bar bar = new Bar();
    bar.setFooList(FooJsonSimplifiedSerializationWrapper.convertFromFoo(Arrays.asList(foo)));

    System.out.println(new ObjectMapper().writeValueAsString(foo));
    System.out.println(new ObjectMapper().writeValueAsString(bar));
}

Этот код напечатает:

Foo serialization: {"id":1,"fooList":[{"id":2,"fooList":[]},{"id":3,"fooList":[]}]}

Bar serialization: {"fooList":[{"id":1,"fooList":[2,3]}]}

Другое решение может включать использование Views с аннотацией @JsonView и настройку представлений для адаптации сериализации к вашим потребностям, но, на мой взгляд, это более громоздкое решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...