阻止杰克逊改变变量名的大小写

Posted

技术标签:

【中文标题】阻止杰克逊改变变量名的大小写【英文标题】:Stop Jackson from changing case of variable names 【发布时间】:2018-03-20 23:48:25 【问题描述】:

我在 Spring 中使用 Jackson 将我的课程序列化为 JSON。当我像下面的示例一样序列化一个类时,Jackson 将某些字段的名称从 Camel Case 更改为小写。我知道我可以通过创建自定义(反)序列化程序来解决这个问题,但我希望在全球范围内关闭它。也许通过在 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);

预期:

"firstName":"first","name":"name","abName":"ab","aName":"a"

实际:

"firstName":"first","name":"name","abName":"ab","aname":"a"

编辑:

将问题缩小到对吸气剂的解释。在 Jackson 中开始看起来像一个错误。

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"

【问题讨论】:

使用@JsonProperty("AName")就完成了 【参考方案1】:

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

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)

【讨论】:

对我来说,此策略将 ISOCountryCode 更改为 IsocountryCode 最新版本为:objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);【参考方案2】:

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

但是,为了支持偶尔使用所有大写名称,我们 检查名称的前两个字符是否都是大写和 如果是这样就别管它了

“FooBah”变成“fooBah”

“Z”变成“z”

“网址”变成“网址”

你有一个带有 aName 字段的边缘案例。因为如果 getter 看起来像 AName() ,那么当你从这个 getter 转换回来时,你应该寻找 AName 字段根据规范。这是附加信息explanation

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

这里是similar question

【讨论】:

如果您使用的类不受您的控制,是否有解决此问题的方法?即来自我无法编辑类的第三方 jar。 @Mick 我想你可以试试jackson mixin 甚至自定义反序列化器(别以为有其他方法【参考方案3】:

虽然我不确定 Jackson 为何将 getAName 读取为 aname,但可以强制 Jackson 使用带有 @JsonProperty("AName") 的某个名称。例如:

class Foo 
    private final String aName;

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

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

(从this 密切相关的问题中获得此解决方案。)

【讨论】:

以上是关于阻止杰克逊改变变量名的大小写的主要内容,如果未能解决你的问题,请参考以下文章

增加悬停链接的字体大小会改变背景颜色大小,如何阻止这种情况?

变量名的第一个字母从大写变为小写

变量名的要求

杰克逊数据绑定枚举不区分大小写

HTML textarea标签大小改变[重复]

纯新手的入门---变量名的声明规范