首页 > 解决方案 > Jackson @JsonValue 与 @JsonTypeInfo 冲突;如何让它们一起工作

问题描述

我正在Jackson使用POJO. 此类POJO由一些字段和一个Map<String,Object> others. 我正在为这个领域Custom Serializer写作。我想避免获取JSON @JsonValue Map @JsonValue @JsonTypeInfo`。我在课堂上需要两个注释,我该如何实现?JSONMAPMap field name "others"´ in my . Hence, I am using the on thefield but using theis conflicting with

截至目前,我得到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")

但是如果我删除它,那么我将不会isA在我的 JSON 中获得该属性。我想知道如何使用 和进行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();
      }
    }
  }
}

标签: javajsonserializationjacksonjackson2

解决方案


尝试设置@JsonTypeInfo.includeJsonTypeInfo.As.EXISTING_PROPERTY

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

推荐阅读