杰克逊动态属性名称

新手上路,请多包涵

我想序列化一个对象,这样其中一个字段将根据字段的类型以不同的方式命名。例如:

 public class Response {
    private Status status;
    private String error;
    private Object data;
        [ getters, setters ]
    }

在这里,我希望将字段 data 序列化为类似 data.getClass.getName() 的字段,而不是总是有一个名为 data 的字段,它包含不同的类型,具体取决于情况.

我如何使用 Jackson 实现这样的技巧?

原文由 Tim 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 469
2 个回答

使用自定义 JsonSerializer

 public class Response {
  private String status;
  private String error;

  @JsonProperty("p")
  @JsonSerialize(using = CustomSerializer.class)
  private Object data;

  // ...
}

public class CustomSerializer extends JsonSerializer<Object> {
  public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeObjectField(value.getClass().getName(), value);
    jgen.writeEndObject();
  }
}

然后,假设您要序列化以下两个对象:

 public static void main(String... args) throws Exception {
  ObjectMapper mapper = new ObjectMapper();
  Response r1 = new Response("Error", "Some error", 20);
  System.out.println(mapper.writeValueAsString(r1));
  Response r2 = new Response("Error", "Some error", "some string");
  System.out.println(mapper.writeValueAsString(r2));
}

第一个将打印:

 {"status":"Error","error":"Some error","p":{"java.lang.Integer":20}}

第二个:

 {"status":"Error","error":"Some error","p":{"java.lang.String":"some string"}}

我使用名称 p 作为包装器对象,因为它仅用作 p 花边架。如果你想删除它,你必须为 整个 类编写一个自定义序列化程序,即 JsonSerializer<Response>

原文由 João Silva 发布,翻译遵循 CC BY-SA 3.0 许可协议

我有一个使用 @JsonAnyGetter 注释的更简单的解决方案,它非常有效。

 import java.util.Collections;
import java.util.Map;

public class Response {
    private Status status;
    private String error;

    @JsonIgnore
    private Object data;

    [getters, setters]

    @JsonAnyGetter
    public Map<String, Object> any() {
        //add the custom name here
        //use full HashMap if you need more than one property
        return Collections.singletonMap(data.getClass().getName(), data);
    }
}

不需要包装器,不需要自定义序列化器。

原文由 tlogbon 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题