杰克逊使用构建器反序列化泛型类型

时间:2013-10-15 23:45:42

标签: generics jackson builder

我正在使用Jackson 2.2.3。我有一个泛型类型,我想从JSON反序列化。我在编译时知道泛型类型的类型参数。当我使用创建器反序列化或使用setter反序列化时,我没有任何问题。但是,当我尝试使用构建器反序列化时,反序列化中使用的类型参数是LinkedHashMap而不是请求的类型。

我认为我理解为什么杰克逊无法确定用于构建器的所需类型参数,因此无法创建所需的参数化类型。那么,如何使用具有泛型类型的构建器?什么是最直接的方式来提示杰克逊使用哪种类型的参数?

以下是我想做的玩具示例。

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());
    }
}

1 个答案:

答案 0 :(得分: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);
}