阻止 Jackson 更改变量名称的大小写

2022-09-02 12:53:56

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

根据默认的 Jackson 命名策略,这不应该发生:

在没有注册的定制策略的情况下,将使用缺省的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);
}

预期:

{“firstName”:“first”,“name”:“name”,“abName”:“ab”,“aName”:“a”}

实际:

{“firstName”:“first”,“name”:“name”,“abName”:“ab”,“aname”:“a”}

编辑:

将问题缩小到对获取器的解释。开始看起来像杰克逊的一个错误。

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"}


答案 1

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

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

“FooBah”变成“fooBah”

“Z”变为“z”

“URL”变为“URL”

并且您有一个带有字段的边缘情况。因为如果 getter 看起来像 ,那么当你从这个 getter 转换回来时,你应该根据规范查找字段。以下是其他信息说明aNameAName()AName

因此,要解决此问题,您可以在字段/getter 上方使用适当的 getter() 或注释getaName()@JsonProperty("aName")

这是类似的问题


答案 2

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

class Foo {
    private final String aName;

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

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

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


推荐