【问题标题】:Serializing a pojo as a nested JSON dictionary将 pojo 序列化为嵌套的 JSON 字典
【发布时间】:2019-07-22 21:25:08
【问题描述】:

鉴于简单的POJO

public class SimplePojo {
    private String key ;
    private String value ;
    private int thing1 ;
    private boolean thing2;

    public String getKey() {
           return key;
    }
    ...
}

我在序列化成这样的东西时没有问题(使用Jackson):

 {
    "key": "theKey",
    "value": "theValue",
    "thing1": 123,
    "thing2": true
  }

但真正让我高兴的是,如果我可以这样序列化该对象:

 {
    "theKey" {
           "value": "theValue",
            "thing1": 123,
            "thing2": true
     }
  }

我想我需要一个自定义序列化程序,但我面临的挑战是插入一个新字典,例如:

@Override
public void serialize(SimplePojo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    gen.writeStartObject();
    gen.writeNumberField(value.getKey(), << Here be a new object with the remaining three properties >> );


}

有什么建议吗?

【问题讨论】:

    标签: java json serialization jackson json-serialization


    【解决方案1】:

    您不需要自定义序列化程序。您可以利用 @JsonAnyGetter 注释生成包含所需输出属性的映射。
    下面的代码采用上述示例 pojo 并生成所需的 json 表示。
    首先,您使用@JsonIgnore 注释所有getter 方法,以便杰克逊在序列化期间忽略它们。唯一会被调用的方法是 @JsonAnyGetter 注释的方法。

    public class SimplePojo {
        private String key ;
        private String value ;
        private int thing1 ;
        private boolean thing2;
    
        // tell jackson to ignore all getter methods (and public attributes as well)
        @JsonIgnore
        public String getKey() {
            return key;
        }
    
        // produce a map that contains the desired properties in desired hierarchy 
        @JsonAnyGetter
        public Map<String, ?> getForJson() {
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> attrMap = new HashMap<>();
            attrMap.put("value", value);
            attrMap.put("thing1", thing1);  // will autobox into Integer
            attrMap.put("thing2", thing2);  // will autobox into Boolean
            map.put(key, attrMap);
            return map;
        }
    }
    

    【讨论】:

    • 那行得通-事实上我确实尝试过(我在原始帖子中忽略了一个事实)。我想我会坚持这一点,尽管我想探索自定义序列化程序选项,因为为了序列化而使用 @JsonAnyGetter 让我的同事们感到困惑。
    【解决方案2】:

    您需要使用writeObjectFieldStart方法写入字段并以相同的类型打开新的JSON Object

    class SimplePojoJsonSerializer extends JsonSerializer<SimplePojo> {
    
        @Override
        public void serialize(SimplePojo value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeStartObject();
    
            gen.writeObjectFieldStart(value.getKey());
            gen.writeStringField("value", value.getValue());
            gen.writeNumberField("thing1", value.getThing1());
            gen.writeBooleanField("thing2", value.isThing2());
            gen.writeEndObject();
    
            gen.writeEndObject();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多