3

I am using Jackson 2.2.3. I have a generic type that I would like to deserialize from JSON. I know at compile time the type argument for the generic type. I have no problems when I deserialize using a creator or deserialize using setters. However, when I attempt to deserialize using a builder, the type argument used in the deserialization is a LinkedHashMap instead of the type requested.

I think that I understand why Jackson cannot determine the desired type argument to use for the builder and therefore cannot create the desired parameterized type. So, how to I go about using a builder with a generic type? What is the most straightforward way to clue Jackson in about which type argument to use?

Here is a toy example of what I would like to do.

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.IOException;

public class Main {
    public static class DesiredTypeArgument {}

    @JsonDeserialize(builder = GenericType.Builder.class)
    public static class GenericType<T> {
        private final T t;

        private GenericType(final T t) {
            this.t = t;
        }

        public T getT() {
            return t;
        }

        public static class Builder<T> {
            private T t;

            public GenericType<T> build() {
                return new GenericType<>(t);
            }

            public Builder<T> withT(final T t) {
                this.t = t;
                return this;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        final ObjectMapper objectMapper = new ObjectMapper()
            .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        final GenericType<DesiredTypeArgument> x = new GenericType.Builder<DesiredTypeArgument>()
            .withT(new DesiredTypeArgument())
            .build();
        final String json = objectMapper.writeValueAsString(x);
        final GenericType<DesiredTypeArgument> y = objectMapper.readValue(json,
            objectMapper.getTypeFactory().constructParametricType(GenericType.class, DesiredTypeArgument.class));
        System.out.println("type argument = " + ((Object) y.getT()).getClass());
    }
}
4

1 回答 1

1

我不确定您是否必须编写自定义反序列化器。如果我了解您的用例,您可以执行以下操作:

static public <T extends Inflatable> List<T> readObjects(List<T> listType, String recType){
    Class c = Class.forName("sfshare." + recType);
    JavaType type = mapper.getTypeFactory().constructParametricType(Result.class, c);   
    Result<T> res = mapper.readValue(rspData, type);
}
于 2015-02-13T15:29:39.807 回答