-
-
Save asavt92/ca55dd4cebd600e69ae79a1af92f7294 to your computer and use it in GitHub Desktop.
This is the correct implementation of @JsonTypeInfo and related annotations when performing polymorphic JSON deserialization on an embedded interface property. It also illustrates the use of an Enum as a type name. See StackOverflow question: http://stackoverflow.com/questions/21485923/java-jackson-polymorphic-json-deserialization-of-an-object-w…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Asset { | |
private AssetType type; | |
@JsonTypeInfo( | |
use = JsonTypeInfo.Id.NAME, | |
include = JsonTypeInfo.As.EXTERNAL_PROPERTY, | |
property = "type" | |
) | |
@JsonSubTypes({ | |
@JsonSubTypes.Type(value = ImageAssetProperties.class, name = "image"), | |
@JsonSubTypes.Type(value = DocumentAssetProperties.class, name = "document") | |
}) | |
private AssetProperties properties; | |
public String getType() { | |
return type.toString(); | |
} | |
@JsonProperty("type") | |
public void setType(String type) { | |
this.type = AssetType.fromString(type); | |
} | |
@JsonIgnore | |
public void setType(AssetType type) { | |
this.type = type; | |
} | |
public AssetProperties getProperties() { | |
return properties; | |
} | |
public void setProperties(AssetProperties properties) { | |
this.properties = properties; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface AssetProperties { | |
String getSource(); | |
AssetProperties setSource(String source); | |
String getProxy(); | |
AssetProperties setProxy(String proxy); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum AssetType { | |
IMAGE("image"), | |
DOCUMENT("document"); | |
private String string; | |
AssetType(String string) { | |
this.string = string; | |
} | |
public static AssetType fromString(String string) { | |
// Enum.valueOf() method is case sensitive; this method is not. | |
if (string != null) | |
for (AssetType assetType : AssetType.values()) | |
if (string.equalsIgnoreCase(assetType.toString())) | |
return assetType; | |
throw new IllegalArgumentException(String.format("%s is not a valid AssetType.", string); | |
} | |
public String toString() { | |
return this.string; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DocumentAssetProperties implements AssetProperties { | |
private String source; | |
private String proxy; | |
public String getSource() { | |
return source; | |
} | |
public DocumentAssetProperties setSource(String source) { | |
this.source = source; | |
return this; | |
} | |
public String getProxy() { | |
return proxy; | |
} | |
public DocumentAssetProperties setProxy(String proxy) { | |
this.proxy = proxy; | |
return this; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImageAssetProperties implements AssetProperties { | |
private String source; | |
private String proxy; | |
private Integer height; | |
private Integer width; | |
public String getSource() { | |
return source; | |
} | |
public ImageAssetProperties setSource(String source) { | |
this.source = source; | |
return this; | |
} | |
public String getProxy() { | |
return proxy; | |
} | |
public ImageAssetProperties setProxy(String proxy) { | |
this.proxy = proxy; | |
return this; | |
} | |
public Integer getHeight() { | |
return height; | |
} | |
public ImageAssetProperties setHeight(Integer height) { | |
this.height = height; | |
return this; | |
} | |
public Integer getWidth() { | |
return width; | |
} | |
public ImageAssetProperties setWidth(Integer width) { | |
this.width = width; | |
return this; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PolymorphicDeserializationTests { | |
@Test | |
public void deserializeJsonSucceeds() { | |
Asset asset = deserializeJson("{ \"type\": \"document\", \"properties\": { \"source\": \"foo\", \"proxy\": \"bar\" } }"); | |
Assert.assertTrue(asset.getProperties() instanceof DocumentAssetProperties); | |
} | |
public Asset deserializeJson(String json) { | |
ObjectMapper mapper = new ObjectMapper(); | |
try { | |
return mapper.readValue(json, Asset.class); | |
} | |
catch(IOException e) { | |
Assert.fail("Could not deserialize JSON.", e); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment