Jackson: Serialize an EER specialization

时间:2016-05-17 11:16:23

标签: java json spring serialization jackson

I'm using spring boot with jackson to provide an API. In my DB there is a generalization/specialization field. That means, I have two fields: a value and a field that defines the data type of the value.

So my entity looks like this:

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

    // getters and setters
}

For example with these three entries:

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

Jackson serialize this as follows:

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

This is what I expteced, but, I need this:

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

So, the values should be serialized according to the value of the "type" field. I know that I can attach a serializer to the "value" field, but I cannot access the "type" field there to know how to serialize the value.

1 个答案:

答案 0 :(得分:1)

如果可以,可以选择更改您的Example类:

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);
    }
}

您的@JsonIgnore

需要public String getValue()