Jackson 子类型 - 如何指定默认值

Jackson subtypes - how to specify a default

我想对子类型做这样的事情。 我有 3 种不同类型的对象:

{
  "value": "string"
}

{
  "value": {
    "type": "obj1"
  }
}

{
  "value": {
    "type": "obj2"
  }
}

value 可以是字符串或对象。

对应的Java类是

public interface Value {
}

public class ValueString implements Value {
    String value;
}

public abstract class ValueObj implements Value{
    public String type;
}

public class ValueObj1 extends ValueObj {
    private Obj1 value;
}

public class ValueObj2 extends ValueObj {
    private Obj2 value;
}

我不介意在 Obj1 和 Obj2 中有一个鉴别器,但是当值只是一个字符串时,没有地方放鉴别器。有没有一种方法可以设置它,以便如果该值是一个字符串,它反序列化为 ValueString,但如果它是一个对象,它反序列化为正确的 ValueObj1 或 ValueObj2?

首先创建自定义反序列化器可以轻松完成:
p.s。我假设您发布的对象只有三种类型。

public class ValueDeserializer extends StdDeserializer<Value> {
    public ValueDeserializer() {
        this(null);
    }

    protected ValueDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Value deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        JsonNode jsonNode = jsonParser.getCodec().readTree(jsonParser);
        if (jsonNode.get("value").isValueNode()) {
            return new ValueString(jsonNode.get("value").asText());
        } else if ("obj1".equals(jsonNode.get("value").get("type").asText())) {
            ValueObj1 valueObj1 = new ValueObj1();
                
            // The logic to handle type obj1
                
            return valueObj1;
        } else {
            ValueObj2 valueObj2 = new ValueObj2();

            // The logic to handle type obj2
                
            return valueObj2;
        }
}

然后简单的用@JsonDeserialize注解classValue如下:

@JsonDeserialize(using = ValueDeserializer.class)
public interface Value {
}

最后,让 Jackson 为您完成剩下的工作:

ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.writeValueAsString(objectMapper.readValue(jsonStr, Value.class)));