具有对象类型的 Jackson JSON 列表

2022-09-03 09:13:54

我必须从对象列表中序列化JSON。生成的 JSON 必须如下所示:

{
    "status": "success",
    "models": [
        {
            "model": {
                "id": 23,
                "color": "red"
            }
        },
        {
            "model": {
                "id": 24,
                "color": "green"
            }
        }
    ]
}

当我简单地序列化它时,我缺少类型/键“模型”:

List<Model> list = new ArrayList<Model>(); // add some new Model(...)
Response r = new Response("success", list); // Response has field "models"

相反,我只是得到这个:

{
    "status": "success",
    "models": [
        {
            "id": 23,
            "color": "red"
        },
        {
            "id": 24,
            "color": "green"
        }
    ]
}

如何为每个对象添加“模型”,而不必使用属性“model”编写一个愚蠢的包装类?

我的类如下所示:

public class Response {
    private String status;
    private List<Model> models;
    // getters / setters
}

public class Model {
    private Integer id;
    private String color;
    // getters / setters
}

答案 1

没有内置的方法可以做到这一点。你必须写你自己的.类似的东西JsonSerializer

class ModelSerializer extends JsonSerializer<List<Model>> {

    @Override
    public void serialize(List<Model> value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException {
        jgen.writeStartArray();
        for (Model model : value) {
            jgen.writeStartObject();
            jgen.writeObjectField("model", model);
            jgen.writeEndObject();    
        }
        jgen.writeEndArray();
    }

}

,然后对字段进行批注,以便它使用它models

@JsonSerialize(using = ModelSerializer.class)
private List<Model> models;

这将序列化为

{
    "status": "success",
    "models": [
        {
            "model": {
                "id": 1,
                "color": "red"
            }
        },
        {
            "model": {
                "id": 2,
                "color": "green"
            }
        }
    ]
}

如果同时序列化和反序列化,则还需要自定义反序列化程序。


答案 2

这是一个古老的问题,但是有一种可以说是更惯用的实现方式(我正在使用):jackson-databind:2.8.8

定义一个(按照 Jackson 的建议进行扩展),该模型以您喜欢的方式打印模型,并使用集合类型:ModelSerializerStdSerializer@JsonSerialize(contentUsing = ...)

class ModelSerializer extends StdSerializer<Model> {

    public ModelSerializer(){this(null);}
    public ModelSerializer(Class<Model> t){super(t);} // sets `handledType` to the provided class

    @Override
    public void serialize(List<Model> value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeObjectField("model", value);
        jgen.writeEndObject();
    }
}

同时,在另一个文件中:

class SomethingWithModels {
    // ...
    @JsonSerialize(contentUsing = ModelSerializer.class)
    private Collection<Model> models;
    // ...
}

现在,您不仅仅局限于模型的 s,而是可以将其应用于 s、s、Native s 甚至 s 的值。ListCollectionSet[]Map