Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Optional in Jackson 2 message converters #24498

Closed
daniel-shuy opened this issue Feb 10, 2020 · 5 comments
Closed

Support Optional in Jackson 2 message converters #24498

daniel-shuy opened this issue Feb 10, 2020 · 5 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@daniel-shuy
Copy link

daniel-shuy commented Feb 10, 2020

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 Collections (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 Collections. Is it possible to apply them to Optional/Page as well?

Currently the workaround is to create custom JsonSerializers 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());
        }
    }
}
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 10, 2020
encircled added a commit to encircled/spring-framework that referenced this issue Apr 6, 2020
@encircled
Copy link
Contributor

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?

@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Apr 24, 2020
@zh32
Copy link

zh32 commented Aug 21, 2020

I can confirm this too. Took me a while to find the cause of my problem.

encircled added a commit to encircled/spring-framework that referenced this issue Jan 30, 2021
encircled added a commit to encircled/spring-framework that referenced this issue Jun 20, 2022
skoarkid pushed a commit to skoarkid/spring-framework that referenced this issue Sep 25, 2022
skoarkid added a commit to skoarkid/spring-framework that referenced this issue Sep 25, 2022
skoarkid added a commit to skoarkid/spring-framework that referenced this issue Sep 25, 2022
@poutsma poutsma self-assigned this Jan 24, 2023
@poutsma poutsma added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jan 24, 2023
@poutsma poutsma added this to the 6.0.5 milestone Jan 24, 2023
@poutsma
Copy link
Contributor

poutsma commented Jan 24, 2023

I don't see a way for Spring Framework to support Spring Data's Page type, so JsonSerializers will still be required for those, but I can add support for Optional.

@poutsma poutsma changed the title Type erasure during serialization of polymorphic JSON in Optional/Page Support Optional in Jackson 2 message converters Jan 24, 2023
@poutsma
Copy link
Contributor

poutsma commented Jan 24, 2023

This is now fixed. Our apologies for taking this long to resolve this issue.

@daniel-shuy
Copy link
Author

@poutsma Thank you! Should I request support for Page in spring-data-commons instead?

mdeinum pushed a commit to mdeinum/spring-framework that referenced this issue Jun 29, 2023
This commit introduces support for Optional in the
AbstractJackson2HttpMessageConverter, similar the existing support for
collection types were supported.

Closes spring-projectsgh-24498
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants