【问题标题】:Jackson JsonPropertyJackson JsonProperty
【发布时间】:2020-06-22 15:34:26
【问题描述】:

我正在尝试使用 jackson @JsonProperty 解析 json 文件。我手头有一个有趣的问题。标记为 @JsonProperty 的字段名称之一可能因输入源而异。下面的示例 json 文件

car1.json --> {"car": {"color": "yellow","type": "luxurySedan"}}
car2.json --> {"car": {"color": "yellow","modeltype": "SUV"}}

我的数据模型类似于

@Data
class Car {

   @JsonProperty("color")
   private String color; 

   @JsonProperty("type")
   private String type; // Don't want to use alias to solve above problem

 }

第二个文件 car2.json 没有被解析。我尝试关注字段类型以从属性文件中获取值(使用弹簧启动),但它没有按预期工作。我不愿意使用alias,纯粹是因为如果任何一个文件的字段名称发生更改,我将不得不更改代码。有人可以帮忙吗

@JsonProperty(@Value("${car.type}")) // Compilation error (It's a spring boot project)
@JsonProperty("${car.type}") // Values not read

【问题讨论】:

  • 这不是有效的 JSON:{color:"yellow", type:"luxurySedan"}。你能检查一下吗?例如,here
  • 更新了我的 JSON
  • 如果你有无限的可能性,就没有简单的方法来实现它。可能最简单的方法是使用@JsonProperty 注释声明所有常量字段,对于其余字段,您可以使用Map@JsonAnySetter 注释。看一看:How to use dynamic property names for a Json object

标签: java jackson


【解决方案1】:

您的 JSON 似乎没有 car 节点,因此您不能将其用作 @JsonProperty 注释的一部分。一般来说,您只需要指定单个节点名称而不是完整路径,因为它们是相对于根节点进行评估的。如果您有嵌套的 JSON 结构,通常会将它们封装在一个单独的类中,因此您仍然不需要放入完整路径。

class Car {

    @JsonProperty("color")
    private String color;

    @JsonProperty("type")
    private String type;

    @JsonProperty("modeltype")
    private String modelType;

    // The rest of the class
}

应该为您提供的 JSON 解决问题。如果源 JSON 中缺少某个属性,那么它的值将只是 Java 对象中的 null

您的第二个 JSON 示例失败,因为 Jackson 尝试将 JSON 解组为的 Java 对象未声明名为 "modeltype" 的属性,默认行为是在未知属性上失败。可以通过添加以下类级别注释来抑制该特定行为:

@JsonIgnoreProperties(ignoreUnknown = true)

但是,这将导致 Jackson 完全忽略任何没有映射字段的属性,因此您将丢失与未知属性关联的任何数据。

【讨论】:

  • 嗨@JonK...没有缺少属性,而是属性名称可以根据输入源动态。想象一下,您从 10 个不同的来源获得相同格式的文件,但属性名称略有变化......这就是我要解决的问题。我不希望 10 个不同的来源有 10 个不同的字段名称,如果每个字段名称不同,情况会更糟
  • @PrashanthG 在这种情况下,您最好将 Java 对象保留为 Map<String, Object>。注释不能将动态值传递给它们 - 它们的参数仅在编译时处理。
  • @PrashanthG 您还可以为您的 Car 类实现自定义反序列化器,尽管在这种特殊情况下我个人不会这样做,因为从可读性/可维护性的角度来看,这有点太多了像黑魔法。拥有 Map 可以更明显地表明您期待一组不可预测的属性。
猜你喜欢
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 2018-04-19
  • 2015-12-26
  • 2021-04-17
  • 1970-01-01
  • 2016-05-07
  • 2018-03-21
相关资源
最近更新 更多