字段上的 @JsonProperty 注释以及 getter/setter

Posted

技术标签:

【中文标题】字段上的 @JsonProperty 注释以及 getter/setter【英文标题】:@JsonProperty annotation on field as well as getter/setter 【发布时间】:2012-07-16 15:11:05 【问题描述】:

我继承了在 getter/setter 上有 @JsonProperty 注释的某个位代码。目的是当使用 Jackson 库序列化对象时,字段具有该特定名称。

当前代码:

private String fileName;

@JsonProperty("FILENAME")
public String getFileName()

    return fileName;


@JsonProperty("FILENAME")
public void setFileName(String fileName)

    this.fileName = fileName;

现在对于另一个工具,我还需要使用 JsonProperty 对字段进行注释。所以这将是我更改的代码:

@JsonProperty("FILENAME")
private String fileName;

@JsonProperty("FILENAME")
public String getFileName()

    return fileName;


@JsonProperty("FILENAME")
public void setFileName(String fileName)

    this.fileName = fileName;

是否有人在字段和 getter/setter 上都使用了相同的注释?我在网上四处张望,但没有看到任何东西。

我已经编译并运行了代码,但我不确定这是否会导致任何问题。对此有什么想法吗?

【问题讨论】:

事实上你不会有问题,因为除了设置值之外,你没有在设置器中做任何事情。但是,如果这种情况发生变化,我会担心杰克逊会使用哪一个;如果它选择了该字段,您可能不会得到您期望的行为。很遗憾,我无法为您找到按优先顺序排列的任何内容。 +1。是的,优先顺序会很有用,但它们当然不应该拥有不同的名称。 【参考方案1】:

根据一些测试,我的观察结果是,与属性名称不同的名称都会生效:

例如。考虑对您的情况稍作修改:

@JsonProperty("fileName")
private String fileName;

@JsonProperty("fileName")
public String getFileName()

    return fileName;


@JsonProperty("fileName1")
public void setFileName(String fileName)

    this.fileName = fileName;

fileName 字段和方法getFileName 都具有正确的属性名称fileNamesetFileName 具有不同的fileName1,在这种情况下Jackson 将在json 中查找fileName1 属性在反序列化点,并将在序列化点创建一个名为fileName1 的属性。

现在,针对您的情况,所有三个 @JsonProperty 都与默认属性名称 fileName 不同,它只会选择其中一个作为属性(FILENAME),并且三个中的任何一个都不同,它会抛出一个异常:

java.lang.IllegalStateException: Conflicting property name definitions

【讨论】:

不,你错了。 fileName 将用于反序列化,fileName1 将用于序列化(版本 2.8.5) 其实getter是用fileName注解的,用于序列化(从对象实例到字符串),而setter,用fileName1注解,将用于反序列化(从字符串到对象实例)跨度> 在字段和 getter 上使用 jsonproperty 的原因是什么?如果你同时使用 getter 和 setter,为什么还要在现场使用它?【参考方案2】:

除了现有的好答案,请注意,Jackson 1.9 通过添加“属性统一”改进了处理,这意味着来自逻辑属性不同部分的所有注释都使用(希望)直观的优先级进行组合。

在 Jackson 1.8 和之前的版本中,在确定序列化的内容和方式(编写 JSON)时,只使用了字段和 getter 注释;并且只有和 setter 注释用于反序列化(读取 JSON)。这有时需要添加“额外”注释,例如同时注释 getter 和 setter。

对于 Jackson 1.9 及更高版本,不需要这些额外的注释。仍然可以添加这些;如果使用不同的名称,则可以创建“拆分”属性(使用一个名称进行序列化,使用另一个名称进行反序列化):这有时对某种重命名很有用。

【讨论】:

有趣。那么在名称不同的情况下不会抛出“冲突名称”错误吗? 不,因为这是合法使用。但是,如果多个 setter/getter 方法之间存在冲突,并且不清楚要使用哪一个,则会有例外。

以上是关于字段上的 @JsonProperty 注释以及 getter/setter的主要内容,如果未能解决你的问题,请参考以下文章

@JsonProperty @JsonIgnoreProperties

带有杰克逊 JsonProperty 的 Lombok 构建器模式

对 kotlin 数据类使用 Jackson @JsonProperty 注释

是否可以获得@JsonProperty 的原始字段名称?

针对枚举验证JSON字段

使用Java,Spring进行基于配置文件,可切换的JSON缩小