java - 强制将属性序列化为 jackson 的身份

标签 java jackson jsonidentityinfo

我有一个类(class)

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

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

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

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

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

当我从此 JSON 反序列化 Bar 实例时:

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

然后我将其序列化回来,我希望输出与输入相同,但它是这样的:

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

最佳答案

您可以创建一个从 Foo 扩展的类类为 fooList 提供替代序列化使用注释@JsonGetter ,就像一个 wrapper 。

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> 转换的方法列表<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注释和自定义 View 以使序列化适应您的需求,但在我看来这是一个更麻烦的解决方案。

关于java - 强制将属性序列化为 jackson 的身份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52390239/

相关文章:

java - 删除 createButtonsForButtonBar 或使其有用 - JFace Dialogs

java - 在 Java 6 的右侧使用泛型?

java - Jackson 根据字段值添加包装器

java - JsonIdentityInfo 用于 hibernate 映射

java - jackson :@JsonIdentityInfo 对象而不是 id

java - 汉字编码?

java - 如何保护 servlet 不被外部用户访问?

kotlin - Jooq:如何将 JSONB 列映射到 Kotlin 数据类字段?

Java如何在序列化过程中使用Jackson ObjectMapper连接Item类中的两个字段?

java - 在 Spring Context 中实例化的 JsonIdentityInfo Resolver