jackson序列化:包裹领域

当我们打开嵌套对象并将其字段写入主对象时,有一个众所周知的情况,我需要做一个反向任务。

我有一个POJO:

class A { private String id = "id1"; @JsonWrap("properties") private String property1 = "..."; @JsonWrap("properties") private String property2 = "..."; // getters and setters } 

默认序列化程序将按预期生成

 { "id": "id1", "property1": "...", "property2": "..." } 

但是,我的JSON应该符合某些规范,为此,我需要将property1property2包装在properties包装器中。 所以结果应该是这样的:

 { "id": "id1", "properties": { "property1": "...", "property2": "..." } } 

我不想改变POJO的结构,所以我看到了3种可能的方法:

  1. 编写自定义序列化器。 但是在我看来,编写这样的序列化器将需要更多的努力,然后手动序列化对象。
  2. 创建代理Java对象,它将反映JSON的正确结构,并序列化此类代理。
  3. 生成后修改JSON。 (我担心重读和重写JSON会有很大的开销)。

有没有人制作这样的Serializer或者可能知道用我需要的结构生成JSON的其他选项?

对于custom serializer我想重用标准BeanSerializer,我不想手动写出所有字段:

  1. 隐藏带注释的字段。
  2. 写出bean,没有带注释的字段,但不要关闭对象。 (不要调用jgen.writeEndObject();
  3. 写出包装的字段。
  4. 关闭对象。

要在不改变模型的情况下获得该function,请查看编写自定义序列化程序以完成jackson无法解决的问题。 我们使用特定的方向注释模型类A以使用已定义的序列化程序,然后使用JsonGenerator专门定义我们之后的结构。

 @JsonSerialize(using = ASerializer.class) class A { private String field1; private String innerField1; private String innerField2; // getters and setters public static class ASerializer extends JsonSerializer { @Override public void serialize(A value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeStringField("field1", value.getField1()); jgen.writeObjectFieldStart("wrapper"); jgen.writeStringField("innerField1", value.getInnerField1()); jgen.writeStringField("innerField2", value.getInnerField2()); jgen.writeEndObject(); jgen.writeEndObject(); } } } 

在这种情况下,我使用了静态内部类,但可行的是,您可以根据可见性将Serializer放置在最适合您的项目结构的位置。 对于一次性特殊情况序列化器,这是我倾向于做的。

听起来你需要创建一个Custom Serializer: http : //wiki.fasterxml.com/JacksonHowToCustomSerializers

当然,如果您从类似的JSON结构创建Java对象,您可能还需要创建自定义反序列化器。

请记住,如果您发现许多对象共享相似的结构,您始终可以使用reflection来创建“通用”序列化程序。

你需要改变你的模型。

 @JsonSerialize(using = ASerializer.class) class A { private String id; private String property1; private String property2; // getters and setters public static class ASerializer extends JsonSerializer { @Override public void serialize(A value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeStartObject(); jgen.writeStringField("id", value.getId()); jgen.writeObjectFieldStart("properties"); jgen.writeStringField("property1", value.getProperty1()); jgen.writeStringField("property2", value.getProperty2()); jgen.writeEndObject(); jgen.writeEndObject(); } } } 

在主要运行:

 A a = new A(); a.setId("id1"); a.setProperty1("..."); a.setProperty2("..."); ObjectMapper mapper = new ObjectMapper(); ObjectWriter writer = mapper.writer(); String json = writer.writeValueAsString(a); System.out.println(json); 

输出:

 {"id":"id1","properties":{"property1":"...","property2":"..."}}