1

我有一堂课

(免责声明,我使用 Kotlin 编写,但我将其翻译成 Java,以便更多人阅读)

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

我想序列化另一个包含Foos 列表的对象,但我希望序列化中的所有条目fooList都是 ID,而不是对象。想到的一种解决方案是在序列化之前以相反的顺序对它们进行拓扑排序,因为它们形成有向无环图。但这显然不是一个完美的解决方案,所以我想知道是否有注释或其他干净的杰克逊方式来做类似的事情。

编辑:
包含 Foo 列表的类如下所示:

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
  ]
}
4

1 回答 1

1

您可以创建一个从Fooclass 扩展的类,以提供fooList使用 annotation的替代序列化@JsonGetter,例如包装器。

Foo班级:

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班级:

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

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

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

FooFooJsonSimplifiedSerializationWrapperFoo序列化的包装器,它有一个转换Lst<Foo>为 List< 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]}]}

另一种解决方案可能涉及使用Viewswith @JsonViewannotation 和自定义视图以使序列化适应您的需求,但我认为这是一个更麻烦的解决方案。

于 2018-09-19T16:38:44.160 回答