杰克逊。 ClassCastException,而value来自泛型类

时间:2014-12-26 11:58:58

标签: java spring generics jackson dto

我有一个DTO

public class FilterSet {

    @JsonProperty("price")
    private IntervalFilter<Double> priceFilter;

    public IntervalFilter<Double> getPriceFilter() {
        return priceFilter;
    }

    public void setPriceFilter(IntervalFilter<Double> priceFilter) {
        this.priceFilter = priceFilter;
    }

    public static class IntervalFilter<T> {

        private IntervalValue<T> value;

        public IntervalValue<T> getValue() {
            return value;
        }

        public void setValue(IntervalValue value) {
            this.value = value;
        }

        public static class IntervalValue<T> {

            private T from;

            private T to;

            public T getFrom() {
                return from;
            }

            public void setFrom(T from) {
                this.from = from;
            }

            public T getTo() {
                return to;
            }

            public void setTo(T to) {
                this.to = to;
            }
        }
    }
}

当我发送priceFilter {“price”:{“value”:{“from”:1.1,“to”:1.2}}}时,没关系。 当我发送priceFilter {“price”:{“value”:{“from”:1.0,“to”:2.0}}}并尝试获取Double值:

Double priceFrom = priceFilter.getValue().getFrom();

我看到java.lang.ClassCastException:java.lang.Integer无法强制转换为java.lang.Double

我做错了什么?

更多信息: Json:{“price”:{“value”:{“from”:1.0,“to”:2.1}}}

我有一个来自Spring控制器的对象FilterSet。在那里,我可以看到一个字段“priceFilter”(类型为IntervalFilter),其字段为“value”(类型为IntervalValue),字段为“from”(类型为Integer),“to”(类型为Double)。

public String getLinks(
            @RequestBody FilterSet filterData
    ) {
        ...
    }

1 个答案:

答案 0 :(得分:3)

可以使用以下JSON(使用整数)来重现错误。

 {"price":{ "value" : { "from" : 1, "to" : 2.1 } } }

为了避免这个问题,必须使用泛型类型声明IntervalValue的所有引用(即使用'&lt;&gt; ), otherwise the raw type is used and it will be considered to be an整数in the example above (which causes the ClassCastException ). When you instead use the generic type, a value of type Double `是强制的,因为它是在代码中声明的。因此,如果你将setter更改为以下内容,它会按预期工作:

public void setValue(IntervalValue<T> value) {
     this.value = value;
}

请注意,参数的类型为IntervalValue<T>,而不是原始代码中的IntervalValue