【问题标题】:Entity properties serialized twice实体属性序列化两次
【发布时间】:2013-10-01 14:19:09
【问题描述】:

在 Spring 3.3 中,我有一个映射到数据库表的实体。在这个实体类中,所有属性都用@JsonProperty 注释,例如@JsonProperty("ID")。 进入控制器,调用服务以使用 DAO/存储库获取这样的实体。这很好用,但是当我使用 @ResponseBody 将此实体发送回请求者时,所有属性都会发送两次。一次按要求,但又一次以小写字母开头,直到出现第一个驼峰字母。 一个例子……

public class MyEntity {
    @JsonProperty("MYSpecialSuperId")
    private String MYSpecialSuperId;

    ...

    public String getMYSpecialSsuperId() {
        return this.MYSpecialSuperId;
    }

}

JSON 字符串化后的结果是:

{ "MYSpecialSuperId":""9", "myspecialSuperId":"9" }

为什么属性在结果中有两次,为什么字母不同???

顺便说一句: 我不建议让 Java 属性以大写字母开头,即使有多个大写字母。

【问题讨论】:

标签: java json spring jackson


【解决方案1】:

Jackson 的ObjectMapper 使用Java bean 模式。换句话说,它期望以下

public class Foo {
    public Object bar;

    public Object getBar() {...}

    public void setBar(Object bar) {...}
}

getter 和 setter 分别以 getset 开头,后跟对应的字段名称,首字母大写。如果您将代码更改为

public class MyEntity {
    @JsonProperty("MYSpecialSuperId")
    private String mySpecialSuperId;

    ...

    public String getMySpecialSuperId() {
        return this.mySpecialSuperId;
    }

}

请注意,该字段以小写my 开头而不是大写(无论@JsonProperty 值如何),我删除了getMYSpecialSsuperId 中多余的s,并使用了小写y。所以现在字段名与getter名匹配,jackson知道属性是一样的,不需要序列化两次。

如果你别无选择,你可以按照Katona posted in the comments和使用

@JsonAutoDetect(getterVisibility=Visibility.NONE)

让杰克逊完全忽略吸气剂,只使用字段来序列化您的 JSON。

【讨论】:

  • 好吧,我没有更改属性名称的选项(但我正在处理这个;))。因此,一些属性的命名如下:ABCDOneOfMyProperty(我讨厌它,但我不得不忍受它)。 @JsonAutoDetect(getterVisibility=Visibility.NONE) 注释起到了作用。谢谢你。 :))
【解决方案2】:

我认为您的访问器中有错字;如果它具有“SsuperId”,则它与字段名称不匹配;因此,field 和 getter 被认为是不同的逻辑属性。

【讨论】:

  • 仅此一项并不能解决整体问题。
  • 问题是由于从getter中提取的名称与字段名称不匹配:我猜是由于非标准命名(多个大写字母作为前缀)。您可能需要为 getter 重复 @JsonProperty 注释。
  • 对不起。我的手指要为这个错字负责。 ;) 在实际代码中,我没有这个错字......只有在问这个问题时才在这里。
  • 我明白这一点。所以那个错字不是原因。但是我要说的是,无论如何,由于名称开头有多个大写字母,因此名称与字段名称和“损坏的”吸气剂名称之间的大小写差异不匹配-不幸的是(甚至可能是杰克逊的名称修饰,wrt Bean规范中的缺陷?),但就是这样。
猜你喜欢
  • 1970-01-01
  • 2020-01-02
  • 2016-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多