【问题标题】:Jackson @JsonValue is conflicting with @JsonTypeInfo; How to make them work togetherJackson @JsonValue 与 @JsonTypeInfo 冲突;如何让他们一起工作
【发布时间】:2021-08-20 07:21:32
【问题描述】:

我正在使用Jackson 序列化POJO。这个POJO 类由一些字段和一个Map<String,Object> others 组成。我在为这个MAP 字段编写JSON 时使用Custom Serializer。我想避免得到Map field name "others"´ in my JSON. Hence, I am using the @JsonValueon theMapfield but using the@JsonValueis conflicting with@JsonTypeInfo`。我在课堂上需要这两个注释,我该如何实现?

截至目前,我得到的JSON 如下:(@JsonValue@JsonTypeInfo

[ "Customer", {
  "name" : "Rise Against",
  "google:sub" : "MyValue-1",
  "age" : "2000"
} ]

我想同时获得JSON@JsonValue@JsonTypeInfo:(如您所见others 键已提交,但其值直接添加到JSON)

{
  "isA" : "Customer",
  "name" : "Batman",
  "google:sub" : "MyValue-1",
  "age" : "2008"
}

我能够获得输出,但我需要从我的班级中删除注释:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")

但如果我删除它,我将不会在我的 JSON 中获得 isA 属性。我想知道如何使Jackson Json Serializer@JsonTypeInfo@JsonValue 一起工作。

不带@JsonTypeInfo但带@JsonValue的输出:

{
  "name" : "Rise Against",
  "google:sub" : "MyValue-1",
  "age" : "2000"
}

输出不带@JsonValue,但带@JsonTypeInfo

{
  "isA" : "Customer",
  "name" : "",
  "age" : "",
  "others" : {
    "name" : "Rise Against",
    "google:sub" : "MyValue-1",
    "age" : "2000"
  }
}

以下是我的Customer类Pojo:

@XmlRootElement(name = "Customer")
@XmlType(name = "Customer", propOrder = {"name", "age", "others"})
@XmlAccessorType(XmlAccessType.FIELD)
@NoArgsConstructor
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
@JsonIgnoreType
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, visible = true, property = "isA")
public class Customer {

  @XmlElement(name = "name", required = true)
  private String name;

  @XmlElement(name = "age", required = true)
  private String age;

  @JsonSerialize(using = CustomExtensionsSerializer.class)
  @XmlJavaTypeAdapter(TestAdapter.class)
  @XmlPath(".")
  @JsonValue
  private Map<String, Object> others = new HashMap<>();

  @JsonAnySetter
  public void setOthers(String key, Object value) {
    others.put(key, value);
  }

  public Map<String, Object> getOthers() {
    return others;
  }
}

以下是我的`自定义序列化程序:

public class CustomExtensionsSerializer extends JsonSerializer<Map<String, Object>> {

  private static final ObjectMapper mapper = new ObjectMapper();

  @Override
  public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeStartObject();
    recusiveSerializer(value, gen, serializers);
    gen.writeEndObject();
  }

  public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    for (Map.Entry<String, Object> extension : value.entrySet()) {
      if (extension.getValue() instanceof Map) {
        //If instance is MAP then call the recursive method
        recusiveSerializer((Map) extension.getValue(), gen, serializers);
      } else if (extension.getValue() instanceof String) {
        //If instance is String directly add it to the JSON
        gen.writeStringField(extension.getKey(), (String) extension.getValue());
      } else if (extension.getValue() instanceof ArrayList) {
        //If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
        gen.writeFieldName(extension.getKey());
        gen.writeStartObject();
        for (Object dupItems : (ArrayList<String>) extension.getValue()) {
          if (dupItems instanceof Map) {
            recusiveSerializer((Map) dupItems, gen, serializers);
          } else {
            gen.writeStringField(extension.getKey(), (String) extension.getValue());
          }
        }
        gen.writeEndObject();
      }
    }
  }
}

【问题讨论】:

    标签: java json serialization jackson jackson2


    【解决方案1】:

    尝试将@JsonTypeInfo.include 设置为JsonTypeInfo.As.EXISTING_PROPERTY

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true, property = "isA")
    

    【讨论】:

    • 您好,感谢您抽出宝贵时间回复。我实际上已经尝试过了。添加这将产生与问题中提供的第一个 JSON 相同的 JSON。它将 Array 作为包装器添加到我的 JSON 中,并且值完全混乱,如下所示:[ "Customer", { "google:main" : { "google:sub" : "MyValue-1" }, "name" : "BATMAN", "age" : "2008" } ]
    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 2023-02-02
    • 2011-07-31
    • 2011-11-19
    • 2017-06-25
    • 2020-12-13
    相关资源
    最近更新 更多