How to use dynamic deserialization on a property using JsonSubTypes?

LEQADA :

I have a class Food which needs to be used as a deserialization class.

public class Food {

    private VegetableConfiguration vegetableConfiguration;
    private Color color;

    // ...
    // Getters/Setters
}
public interface VegetableConfiguration {
    // ...
}
public class PotatoConfiguration implements VegetableConfiguration {
    // ...
}
public class CarrotConfiguration implements VegetableConfiguration {
    // ...
}
public class PepperConfiguration implements VegetableConfiguration {
    // ...
}
public enum Color {
    BROWN, ORANGE, RED
}

I need to select an implementation VegetableConfiguration based on Color I get from the response.

I'm trying to use JsonTypeInfo form Jackson. According to JavaDoc it can be used on a property.

public class Food {


    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            property = "color")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = PotatoConfiguration.class, name = "BROWN"),
            @JsonSubTypes.Type(value = CarrotConfiguration.class, name = "ORANGE"),
            @JsonSubTypes.Type(value = PepperConfiguration.class, name = "RED"),
    })
    private VegetableConfiguration vegetableConfiguration;
    private Color color;

    // ...
    // Getters/Setters
}

but it fails with the following error

org.springframework.web.client.RestClientException: Error while extracting response for type [Food] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Missing type id when trying to resolve subtype of [simple type, class VegetableConfiguration]: missing type id property 'color' (for POJO property 'vegetableConfiguration'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class VegetableConfiguration]: missing type id property 'color' (for POJO property 'vegetableConfiguration')

How to make it select an implementation for VegetableConfiguration on deserialization depending on color?

Preferably without implementing a custom deserializer.

Michał Ziober :

You need to use JsonTypeInfo.As.EXTERNAL_PROPERTY. From documentation:

Inclusion mechanism similar to PROPERTY, except that property is included one-level higher in hierarchy, i.e. as sibling property at same level as JSON Object to type. Note that this choice can only be used for properties, not for types (classes). Trying to use it for classes will result in inclusion strategy of basic PROPERTY instead.

See also:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=174130&siteId=1