杰克逊 Java 对象映射无法报告不存在的'known properties'



我有一个JSON对象,它被映射到一个Java对象。JSON包含Java Object处理的嵌套数据。我的案例很大,所以我将使用一个精简的版本作为我所尝试的示例。

我的JSON数据是这样的:

{"name":"wmi", "data": [{"ip":"192.168.1.50", "L2CacheSize":"1024", "L2CacheSpeed":"0"}, {"ip":"192.168.1.51", "L2CacheSize":"1024", "L2CacheSpeed":"0"}] }

,其中数据字段保存了一个JSON对象列表。它通过Jackson映射到我的Java对象,看起来像这样:

public class WmiData {
    private String name;
    private List<Computer> data;
    //Getters and Setters...
    //Constructor
    public WmiData(String name, List<Computer> computers) {
        this.name = name;
        this.data = computers;
    }
    static class Computer {
        private String ip;
        private Integer L2CacheSize;
        private Integer L2CacheSpeed;
        public Computer(String ip, Integer L2CacheSize, Integer L2CacheSpeed) {
            this.ip = ip;
            this.L2CacheSize = L2CacheSize;
            this.L2CacheSpeed = L2CacheSpeed;
        }
        //Getters and Setters...
    }
}

,我做了一个简单的映射,像这样:

ObjectMapper mapper = new ObjectMapper();
WmiData data = mapper.readValue(jsonString, WmiData.class);

但是,解析失败,给出错误:

SEVERE: Failure to convert json to object:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "L2CacheSize" (class company.Data.Wmi$Computer), not marked as ignorable (3 known properties: , "ip", "l2CacheSize", "l2CacheSpeed")
 at [Source: {"data":[{"L2CacheSize":"1024","ip":"192.168.1.50","L2CacheSpeed":"0"}, {"L2CacheSize":"1024","ip":"192.168.1.51","L2CacheSpeed":"0"}],"name":"wmi"}; line: 1, column: 26] (through reference chain: company.Data.Wmi["data"]->company.Data.Computer["L2CacheSize"])
        at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
        at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:568)
        at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:649)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:830)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:310)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
        at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
        at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
        at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
        at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:338)
        at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:87)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:290)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2563)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1805)
        at uk.co.humboldt.Sums.Service.MessageHandler.getPoll(MessageHandler.java:93)
        at uk.co.humboldt.Sums.Service.MessageHandler.pollWmi(MessageHandler.java:147)
        at uk.co.humboldt.Sums.Service.MessageHandler.pollServices(MessageHandler.java:105)
        at uk.co.humboldt.Sums.Service.MessageHandler.lambda$new$0(MessageHandler.java:72)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

上面的错误解释了Jackson只知道三个已知的属性ip, l2CacheSizel2CacheSpeed,其中两个在我的对象定义中不存在。我的字段是L2CacheSizeL2CacheSpeed,注意两者中的大写'L'。它似乎在抱怨它与之不兼容的数据源清楚地表明,传入的数据与我的Java对象所描述的格式完全相同,但仍然失败。

有什么问题吗?

您看到的问题是由于Jackson使用Java Bean命名约定来找出Java类中的Json属性。

所以,为了解决这个问题,你可以把你的属性名称改为Jackson说他"知道"的那些,或者用@JsonProperty("L2CacheSize")作为例子注释它。

static class Computer {
    private String ip;
    @JsonProperty("L2CacheSize")
    private Integer L2CacheSize;
    @JsonProperty("L2CacheSpeed")
    private Integer L2CacheSpeed;
    public Computer(String ip, Integer L2CacheSize, Integer L2CacheSpeed) {
        this.ip = ip;
        this.L2CacheSize = L2CacheSize;
        this.L2CacheSpeed = L2CacheSpeed;
    }
    //Getters and Setters...
}

只需设置DeserializationFeature。FAIL_ON_UNKNOWN_PROPERTIES设置为false

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
WmiData data = mapper.readValue(jsonString, WmiData.class);

最新更新