Skip to content

NoCtorDeser can not deserialize parameterized types #193

@luozhenyu

Description

@luozhenyu

Code

The following code throws java.lang.ClassCastException. The type of response.getPayload() is not User but LinkedHashMap

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.module.noctordeser.NoCtorDeserModule;

public class Demo {

    public static class Response<T> {

        private final T payload;

        public Response(T payload) {
            this.payload = payload;
        }

        public T getPayload() {
            return payload;
        }
    }

    public static class User {

        private final String name;

        public User(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    public static void main(String[] args) throws Exception {
        String json = "{\"payload\":{\"name\":\"jackson\"}}";
        JsonMapper mapper = JsonMapper.builder()
            .addModule(new NoCtorDeserModule())
            .build();

        ObjectReader objectReader = mapper.readerFor(new TypeReference<Response<User>>() {
        });
        Response<User> response = objectReader.readValue(json);
        System.out.println(response.getPayload().getClass());
    }
}

Cause

@cowtowncoder It seems the JsonDeserializer is fetched by Class<?> instClass rather than a ParameterizedType.

https://github.com/FasterXML/jackson-modules-base/blob/2.15/no-ctor-deser/src/main/java/com/fasterxml/jackson/module/noctordeser/MissingInstantiatorHandler.java#L34-L37

Solution

The overrided method DeserializationProblemHandler#handleMissingInstantiator(DeserializationContext ctxt, Class<?> instClass, ValueInstantiator valueInst, JsonParser jsonParser, String msg) does not suppy generic information. Maybe we can extend class AnnotatedWithParams and override its public abstract Object call() throws Exception;. Then we set it to the StdValueInstantiator's _defaultCreator field?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions