Java 如何将JSON反序列化到接口?

Java 如何将JSON反序列化到接口?,java,json,jackson,polymorphism,deserialization,Java,Json,Jackson,Polymorphism,Deserialization,我无法将JSON反序列化到以下示例中实现Basic接口的一些类ChildA、ChildB等 @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = InstagramUser.class, name = "Ch

我无法将JSON反序列化到以下示例中实现Basic接口的一些类ChildAChildB

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = InstagramUser.class, name = "ChildA")
})
public interface Basic {
    getName();
    getCount();
}

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeName("ChildA")
public class ChildA implements Basic { ... }

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeName("ChildB")
public class ChildB implements Basic { ... }
...

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Response<E extends Basic> {
    @JsonProperty("data")
    private List<E> data;

    public List<E> getData() {
        return data;
    }

    public void setData(List<E> data) {
        this.data = data;
    }
}

// deserialization
HTTPClient.objectMapper.readValue(
    response, 
    (Class<Response<ChildA>>)(Class<?>) Response.class
)
没有在所有类型对象中显示的属性,因此它们完全不同。但正如您在readValue行中看到的,我知道预期的类型。如何构造JsonTypeInfoJsonSubTypes注释以按预期类反序列化JSON?

我找到的不是确切的解决方案,而是一种变通方法。我使用自定义响应类ChildAResponse并将其传递给
ObjectMapper.readValue()
方法

类ChildAResponse扩展响应{}
//反序列化
HTTPClient.objectMapper.readValue(
答复,,
儿童体育课
)

因此,不再需要接口上的JsonTypeInfo和JsonSubTypes注释。

根据这里的阅读,我有点像你一样的问题:我创建了我自己的解决方案,它基本上包括创建我自己的反序列化程序,诀窍是使用/标识JSON中的特定属性,以了解反序列化应返回的实例类型,例如:

public interface Basic {
}
第一个孩子:

public class ChildA implements Basic {
    private String propertyUniqueForThisClass;
    //constructor, getters and setters ommited
}
第二个孩子:

public class ChildB implements Basic {
    private String childBUniqueProperty;
    //constructor, getters and setters ommited
}
反序列化程序(BasicDeserializer.java)类似于:

public class BasicDeserializer extends StdDeserializer<Basic> {


    public BasicDeserializer() {
        this(null);
    }

    public BasicDeserializer(final Class<?> vc) {
        super(vc);
    }

    @Override
    public Basic deserialize(final JsonParser jsonParser,
                               final DeserializationContext deserializationContext)
            throws IOException {

        final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        final ObjectMapper mapper = (ObjectMapper) jsonParser.getCodec();

        // look for propertyUniqueForThisClass property to ensure the message is of type ChildA
        if (node.has("propertyUniqueForThisClass")) {
            return mapper.treeToValue(node, ChildA.class);
            // look for childBUniqueProperty property to ensure the message is of type ChildB
        } else if (node.has("childBUniqueProperty")) {
            return mapper.treeToValue(node, ChildB.class);
        } else {
            throw new UnsupportedOperationException(
                    "Not supported class type for Message implementation");
        }
    }
}
对于测试:

@Test
public void testJsonToChildA() throws IOException {
    String message = "{\"propertyUniqueForThisClass\": \"ChildAValue\"}";
    Basic basic = BasicUtils.buildMessageFromJSON(message);
    assertNotNull(basic);
    assertTrue(basic instanceof ChildA);
    System.out.println(basic);
}
@Test
public void testJsonToChildB() throws IOException {
    String message = "{\"childBUniqueProperty\": \"ChildBValue\"}";
    Basic basic = BasicUtils.buildMessageFromJSON(message);
    assertNotNull(basic);
    assertTrue(basic instanceof ChildB);
    System.out.println(basic);
}

源代码可以在以下位置找到:

是您要在json中反序列化的类型吗?数据中的对象是预期格式(ChildA),但没有包含类型信息的属性。列表中的所有对象都相同。不幸的是,我无法更改JSON。这就是问题所在——您的注释告诉jackson在JSON中需要一个类型,但没有
private static final ObjectMapper MAPPER;

// following good software practices, utils can not have constructors
private BasicUtils() {}

static {
    final SimpleModule module = new SimpleModule();
    MAPPER = new ObjectMapper();
    module.addDeserializer(Basic.class, new BasicDeserializer());
    MAPPER.registerModule(module);
}

public static String buildJSONFromMessage(final Basic message)
        throws JsonProcessingException {
    return MAPPER.writeValueAsString(message);
}

public static Basic buildMessageFromJSON(final String jsonMessage)
        throws IOException {
    return MAPPER.readValue(jsonMessage, Basic.class);
}
@Test
public void testJsonToChildA() throws IOException {
    String message = "{\"propertyUniqueForThisClass\": \"ChildAValue\"}";
    Basic basic = BasicUtils.buildMessageFromJSON(message);
    assertNotNull(basic);
    assertTrue(basic instanceof ChildA);
    System.out.println(basic);
}
@Test
public void testJsonToChildB() throws IOException {
    String message = "{\"childBUniqueProperty\": \"ChildBValue\"}";
    Basic basic = BasicUtils.buildMessageFromJSON(message);
    assertNotNull(basic);
    assertTrue(basic instanceof ChildB);
    System.out.println(basic);
}