阻止杰克逊改变变量名称的案例

时间:2017-10-09 17:35:08

标签: java spring-boot jackson

我在Spring使用Jackson将我的类序列化为JSON。当我像下面的例子一样序列化一个类时,Jackson正在将某些字段的名称从Camel Case更改为小写。我知道我可以通过创建自定义(de)序列化器来解决这个问题,但我希望能够全局关闭它。也许通过在application.properties中设置属性。

根据default Jackson naming strategy,这不应该发生:

  

如果没有注册的自定义策略,则使用默认的Java属性命名策略,它将字段名称保留为...

class Foo {
    private final String firstName;
    private final String aName;
    private final String name;
    private final String abName;

    Foo(final String firstName, final String aName, final String name, final String abName) {
        this.firstName = firstName;
        this.aName = aName;
        this.name = name;
        this.abName = abName;
    }
    // Getters here
}

public static void main(String[] args) {
        final ObjectMapper mapper = new ObjectMapper();
        final Foo foo  = new Foo("first", "a", "name", "ab");
        final String jsonInString = mapper.writeValueAsString(foo);
        System.out.println(jsonInString);
}

预期:

{ “名字”: “第一”, “名称”: “姓名”, “abName”: “AB”, “的 aName ”: “一个”}

实际

{ “名字”: “第一”, “名称”: “姓名”, “abName”: “AB”, “的 aname ”: “一个”}

修改

将问题缩小到解释吸气剂。开始看起来像杰克逊的一个错误。

class Foo {
    private final String aName;

    Foo(final String aName) {
        this.aName = aName;
    }

    public String getaName() {
        return this.aName;
    }
}

序列化为{"aName":"a"}

然而,

class Foo {
    private final String aName;

    Foo(final String aName) {
        this.aName = aName;
    }

    public String getAName() {
        return this.aName;
    }
}

序列化为{"aname":"a"}

3 个答案:

答案 0 :(得分:9)

这里的问题更多地是关于JavaBeans(TM) Specification。根据规范(第58页)

  

但是为了支持偶尔使用所有大写名称,我们   检查名称的前两个字符是否都是大写的   如果是这样的话,请不要这样做。

     

“FooBah”变成“fooBah”

     

“Z”变为“z”

     

“网址”变为“网址”

你有AName()字段的边缘情况。因为如果getter看起来像AName,那么当您从此getter转换回来时,您应该根据规范查找getaName()字段。以下是其他信息explanation

为了解决这个问题,您可以在字段/ getter上方使用正确的getter(@JsonProperty("aName"))或form=ModelForm()注释

这是similar question

答案 1 :(得分:2)

虽然我不确定杰克逊为什么会将getAName读到aname,但可以强迫杰克逊使用某个名称@JsonProperty("AName")。例如:

class Foo {
    private final String aName;

    Foo(final String aName) {
        this.aName = aName;
    }

    @JsonProperty("AName")
    public String getAName() {
        return this.aName;
    }
}

(从this密切相关的问题得到这个解决方案。)

答案 2 :(得分:0)

您还可以在Objectmapper中使用PropertyNamingStrategy选项。

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)