Affects: 5.2.3.RELEASE
Given an endpoint that returns a polymorphic JSON type, eg.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({Impl1.class, Impl2.class})
public interface Parent {
}
public class Impl1 implements Parent {
}
public class Impl2 implements Parent {
}
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Parent get() {
return new Impl1();
}
Jackson will serialize it with the property @type
, eg.
{
"@type": "Impl1"
}
However, when wrapping it with an Optional
/Page, the JSON polymorphism no longer works. Eg.
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Optional<Parent> getOptional() {
return Optional.of(new Impl1());
}
returns:
{}
According to FasterXML/jackson-databind#1594 this is due to type erasure, however the JSON polymorphism still works when wrapping with built-in Collection
s (eg. List
/Set
/Map
), eg.
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Collection<Parent> getCollection() {
return Collections.singleton(new Impl1());
}
So it seems like Spring has special handling for built-in Collection
s. Is it possible to apply them to Optional
/Page as well?
Currently the workaround is to create custom JsonSerializer
s for Optional
/Page, eg.
@JsonComponent
public class OptionalSerializer extends JsonSerializer<Optional<?>> {
@Override
public void serialize(Optional<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value.isPresent()) {
gen.writeObject(value.get());
}
}
}
Comment From: encircled
Hi.
I can confirm this issue. It works for collections thanks to Jackson support.
My PR fixes "Optional" only, for the Page it should be placed in a different repo I believe, spring-data-rest maybe?
Comment From: zh32
I can confirm this too. Took me a while to find the cause of my problem.
Comment From: poutsma
I don't see a way for Spring Framework to support Spring Data's Page
type, so JsonSerializer
s will still be required for those, but I can add support for Optional
.
Comment From: poutsma
This is now fixed. Our apologies for taking this long to resolve this issue.
Comment From: daniel-shuy
@poutsma Thank you! Should I request support for Page
in spring-data-commons instead?