【问题标题】:Jackson Java Object mapping fails reporting non-existent 'known properties'Jackson Java 对象映射无法报告不存在的“已知属性”
【发布时间】:2016-11-01 17:37:13
【问题描述】:

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

我的 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)

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

可能是什么问题?

感谢任何帮助。

【问题讨论】:

  • L2CacheSize 是一个字符串,你用一个 int 映射它,把它改成字符串类型。

标签: java json jackson objectmapper


【解决方案1】:

您看到的问题是由于 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...

}

【讨论】:

  • 在对包含更简单变量名的类执行相同操作时,我没有遇到此问题。这真的只是杰克逊在寻找专门的骆驼大小写变量名称吗?
  • 是的,正如我指出的杰克逊使用 Java bean 命名约定,即名称必须是驼峰大小写,还有其他规则,但是如果你命名你的名字,你违反的是驼峰大小写像 l2CacheSize 这样的变量应该可以在没有注释的情况下工作
  • 恕我直言,这似乎设计得很糟糕,因为它本质上将已定义的变量名称转换为不正确的变量名称。在这种情况下,它没有明确的属性定义作为强制性的,这是没有意义的,因为默默地遵守命名约定似乎会产生误导、混淆和错误。感谢您的帮助。
  • 嘿 Shiri,使用它是有原因的,它是一种获取类信息的技术,例如不需要过多使用反射的字段和方法,否则它会慢的。我忘记了该技术的名称,但这只是为了替换反射的使用,问题在于生成的 getter 和 setter 方法,根据 Beans 约定,getter 应该是 get + 驼峰后的变量名称,因为你的getter 将是 L2CacheSize 它将假定属性是 l2CacheSize,因此遵循约定。
  • 感谢肯尼迪的回复。你已经把事情弄清楚了,非常感谢!
【解决方案2】:

只需将 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2022-10-23
    相关资源
    最近更新 更多