将 @JsonIdentityInfo 与 @JsonSerialize 以及自定义转换器一起使用

发布于 2025-01-14 12:02:04 字数 2584 浏览 3 评论 0原文

我试图通过首先将对象转换为另一个对象来序列化对象。同时,我不想序列化同一对象两次,因此我仅在第一次使用 @JsonIdentityReference 来序列化它。然而,由于转换器始终会为同一输入对象创建新的输出对象,因此每次都会对整个对象进行序列化。有没有办法避免在使用转换器的同时序列化同一对象两次?

Domain 类

@JsonSerialize(converter = BooleanWithNameConverter.class)
@JsonDeserialize(converter = BooleanWithNameDtoConverter.class)
public class BooleanWithName {

    private final boolean value;
    private final String name;
    
    BooleanWithName(String name, boolean value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public boolean getValue() {
        return value;
    }
}

DTO

@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
public class BooleanWithNameDto {

    private final boolean value;
    private final String name;
    
    @JsonCreator
    BooleanWithNameDto(@JsonProperty("name") String name, @JsonProperty("value") boolean value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public boolean getValue() {
        return value;
    }
}

DTO 的转换器

public class BooleanWithNameConverter extends StdConverter<BooleanWithName, BooleanWithNameDto> {

    @Override
    public BooleanWithNameDto convert(BooleanWithName obj) {
        return new BooleanWithNameDto(obj.getName(), obj.getValue());
    }
}

返回域对象的转换器

这并不是严格需要的,因为仅通过检查 json 字符串就可以看到问题,但有助于添加一个小型单元测试来演示问题

public class BooleanWithNameDtoConverter extends StdConverter<BooleanWithNameDto, BooleanWithName> {

    @Override
    public BooleanWithName convert(BooleanWithNameDto obj) {
        return new BooleanWithName(obj.getName(), obj.getValue());
    }
}

一个小单元测试失败

public class UnitTest {

    @Test
    public void testConverter() throws JsonProcessingException {
        BooleanWithName booleanWithName = new BooleanWithName("dummy", true);
        ObjectMapper objectMapper = new ObjectMapper();
        BooleanWithName[] value = { booleanWithName, booleanWithName };
        BooleanWithName[] readValue = objectMapper.readValue(objectMapper.writeValueAsString(value), BooleanWithName[].class);
        Assertions.assertEquals(readValue[0], readValue[1]);
    }
}

非常感谢!

I am trying to serialise an object by converting it first to another object. At the same time I do not want to serialise twice the same object so I am using @JsonIdentityReference to serialise it only the first time. However since the converter will always create a new output object for the same input object the entire object is serialised every time. Is there a way to avoid serialising twice the same object while at the same time using a converter?

The Domain class

@JsonSerialize(converter = BooleanWithNameConverter.class)
@JsonDeserialize(converter = BooleanWithNameDtoConverter.class)
public class BooleanWithName {

    private final boolean value;
    private final String name;
    
    BooleanWithName(String name, boolean value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public boolean getValue() {
        return value;
    }
}

The DTO

@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)
public class BooleanWithNameDto {

    private final boolean value;
    private final String name;
    
    @JsonCreator
    BooleanWithNameDto(@JsonProperty("name") String name, @JsonProperty("value") boolean value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public boolean getValue() {
        return value;
    }
}

The converter to the DTO

public class BooleanWithNameConverter extends StdConverter<BooleanWithName, BooleanWithNameDto> {

    @Override
    public BooleanWithNameDto convert(BooleanWithName obj) {
        return new BooleanWithNameDto(obj.getName(), obj.getValue());
    }
}

The converter back to the domain object

This is not strictly needed since the problem can be seen just by examining the json string but helpful in order to add a small unit test demonstrating the problem

public class BooleanWithNameDtoConverter extends StdConverter<BooleanWithNameDto, BooleanWithName> {

    @Override
    public BooleanWithName convert(BooleanWithNameDto obj) {
        return new BooleanWithName(obj.getName(), obj.getValue());
    }
}

A small unit test that fails

public class UnitTest {

    @Test
    public void testConverter() throws JsonProcessingException {
        BooleanWithName booleanWithName = new BooleanWithName("dummy", true);
        ObjectMapper objectMapper = new ObjectMapper();
        BooleanWithName[] value = { booleanWithName, booleanWithName };
        BooleanWithName[] readValue = objectMapper.readValue(objectMapper.writeValueAsString(value), BooleanWithName[].class);
        Assertions.assertEquals(readValue[0], readValue[1]);
    }
}

Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文