java - Jackson:序列化 EER 特化

标签 java json spring serialization jackson

我使用 spring boot 和 jackson 来提供 API。 在我的数据库中有一个泛化/特化字段。这意味着,我有两个字段:一个值和一个定义该值的数据类型的字段。

所以我的实体看起来像这样:

public class Example{
    private String value;
    private String type;

    // getters and setters
}

例如,这三个条目:

"1234";"Integer"
"example string";"String"
"true";"Boolean"

jackson 将其序列化如下:

[{
    "value": "1234",
    "type": "Integer"
},
{
    "value": "example string",
    "type": "String"
},
{
    "value": "true",
    "type": "Boolean"
}]

这就是我所期望的,但是,我需要这个:

[{
    "value": 1234,
    "type": "Integer"
},
{
    "value": "example string",
    "type": "String"
},
{
    "value": true,
    "type": "Boolean"
}]

因此,这些值应该根据“type”字段的值进行序列化。 我知道我可以将序列化器附加到“值”字段,但我无法访问那里的“类型”字段以了解如何序列化该值。

最佳答案

如果可以的话,一个选择是像这样更改示例类:

public static class Example {
    private String value;
    private String type;

    @JsonIgnore
    public String getValue() {
        return value;
    }

    @JsonProperty("value")
    @JsonRawValue
    public Object getRawValue() {
        if("String" .equals(type)){
            return '"'+ value +'"';
        }
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

或者您可以在Example类上使用反序列化器

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addSerializer(Example.class, new MySerializer());
    mapper.registerModule(module);
    System.out.println(mapper.writeValueAsString(list));
}

private static class MySerializer extends JsonSerializer<Example> {
    @Override
    public void serialize(Example value, JsonGenerator gen, SerializerProvider serializers)
                                                                      throws IOException {
        gen.writeStartObject();

        gen.writeFieldName("value");

        if (value.getType().equals("String")) {
            gen.writeString( value.getValue());
        } else {
            gen.writeRawValue(value.getValue());
        }

        gen.writeStringField("type", value.getType());
        gen.writeEndObject();
    }
}

结果:

[{"value":1234,"type":"Integer"},{"value":"example string","type":"String"},{"value":true,"type":"Boolean"}]
<小时/>

更新

以下是一种使用自定义反序列化器并为每个其他字段使用默认反序列化器的方法:

private static class MySerializer extends JsonSerializer<Example> {
    private static final ObjectMapper internalMapper = new ObjectMapper();

    @Override
    public void serialize(Example value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        ObjectNode node = internalMapper.valueToTree(value);

        if (value.getType().equals("String")) {
            node.put("value", value.getValue());
        } else {
            node.putRawValue("value", new RawValue(value.getValue()));
        }

        gen.writeObject(node);
    }
}

需要在 public String getValue() 中包含 @JsonIgnore

关于java - Jackson:序列化 EER 特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37274563/

相关文章:

json - 是否可以 'inject' 引用 JSON 架构

java - 无论我做什么都无法安装 spring-boot-starter-parent

spring - 多个访问 token 和一个刷新 token

java - JPQL 选择实体并获取属于所选实体的集合的计数

json - 在 Common Lisp 中访问嵌套的 JSON 字段

json - Spring Boot 在 json 中包含 ID 字段

Spring,跳过(空)配置文件

java - 如何使用 Eclipse 使用行注释将 Java 从 Allman 重新格式化为 K&R?

Java-ajax跨站空响应字符串

java - 为什么java有new?