杰克逊无法反序列化Optional,抛出NoSuchFieldError

时间:2018-09-17 19:45:12

标签: json spring-boot jackson optional

我想在类中使用Optional类型,但是每次杰克逊尝试将传入的JSON反序列化为Java类时,都会出现错误

java.lang.NoSuchFieldError: _valueInstantiator
    at com.fasterxml.jackson.datatype.jdk8.OptionalDeserializer.withResolved(OptionalDeserializer.java:38) ~[jackson-datatype-jdk8-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.datatype.jdk8.OptionalDeserializer.withResolved(OptionalDeserializer.java:10) ~[jackson-datatype-jdk8-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.deser.std.ReferenceTypeDeserializer.createContextual(ReferenceTypeDeserializer.java:74) ~[jackson-databind-2.8.10.jar:2.8.10]
    at com.fasterxml.jackson.databind.DeserializationContext.handlePrimaryContextualization(DeserializationContext.java:650) ~[jackson-databind-2.8.10.jar:2.8.10]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:490) ~[jackson-databind-2.8.10.jar:2.8.10]
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293) ~[jackson-databind-2.8.10.jar:2.8.10]

我知道已经有一个关于此的主题:Jackson deserializing Optional throws NoSuchFieldError和 我已经尝试将jackson-java8扩展名更改为较旧的类型,但是没有任何效果。当我使用2014年以来的版本时,我总是收到noSuchFieldError或只是一个空指针异常。有人可以告诉我是否还有其他可以尝试的方法?因为我真的想使用Optionals,所以谢谢。这是java类的代码。第一个字段会导致错误:

public class SeedRecordQuery {
    private Optional<List<Double>> monthlyTemperatureCurve;
    private Optional<FilterWrapper> filterWrapper;

    public Optional<List<Double>> getMonthlyTemperatureCurve() {
        return monthlyTemperatureCurve;
    }

    public void setMonthlyTemperatureCurve(Optional<List<Double>> monthlyTemperatureCurve) {
        this.monthlyTemperatureCurve = monthlyTemperatureCurve;
    }

    public Optional<FilterWrapper> getFilterWrapper() {
        return filterWrapper;
    }

    public void setFilterWrapper(Optional<FilterWrapper> filterWrapper) {
        this.filterWrapper = filterWrapper;
    }
}

我尝试使用无类型的Optional,但是会发生相同的错误,因此该错误不是由通用类型List<Double>引起的

编辑:我做了一个变通办法,使我可以将JSON值作为可选值,但并不理想:

private List<Double> monthlyTemperatureCurve;
private FilterWrapper filterWrapper;
@JsonIgnore
private Optional<List<Double>> monthlyTemperatureCurveOptional;
@JsonIgnore
private Optional<FilterWrapper> filterWrapperOptional;

public SeedRecordQuery() {
    monthlyTemperatureCurveOptional = Optional.ofNullable(monthlyTemperatureCurve);
    filterWrapperOptional = Optional.ofNullable(filterWrapper);
}

1 个答案:

答案 0 :(得分:0)

您的依赖项中需要jackson-datatype-jdk8,但还需要在映射器中注册Jdk8Module

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
String json = "{\"monthlyTemperatureCurve\":[2.5,4.3]}";
SeedRecordQuery seedRecordQuery = mapper.readValue(json, SeedRecordQuery.class);

修改

如果您在spring应用程序中使用全局配置的ObjectMapper,则必须根据需要进行配置:

@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        return mapper;
    }
}