JSON首字母大写问题 | 深入源码解析

简单说两句

✨ 正在努力的小新~
💖 超级爱分享,分享各种有趣干货!
👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板
🌈 感谢关注,关注了你就是我的超级粉丝啦!
🔒 以下内容仅对你可见~

作者:后端小知识CSDN后端领域新星创作者 |阿里云专家博主

CSDN个人主页后端小知识

🔎GZH后端小知识

🎉欢迎关注🔎点赞👍收藏⭐️留言📝

image-20240330160209797

前言

Hello亲爱的友友们,好久不见吖,之所以这么久没有更新博客,是因为最近在赶一个专项,加班比较多🧑‍💻

image-20240330140426825

今天我们来给大家讲解一下我在项目中遇到的一个坑吧~

梦回上周,遇到这样一个比较特殊的需求,就是返回给前端的字段需要用大写开头

image-20240330140833190

一般情况下,Java的字段命名规范都是采用小驼峰命名,不过为了满足前端的需要,得改成大驼峰的方式😤

不过当时觉得也很Easy,心想,直接给改成大写不就完事了么☺️

我用ChatGPT快速改完后,直接开始运行,满怀期待,结果啪啪打脸了

image-20240330141319470

输出的结果还是小驼峰形式,无了个大语~

下面开始疯狂的在网上查询资料…

案例

为了表现得更直观,我这里举一个小荔枝哈🌰,就不用公司的代码了,我可不想进去😉😉

image-20240330142151676

我们在SpringBoot项目中创建一个Animal实体类,给一个name属性,首字母大写

Animal代码清单

public class Animal {
    private String Name;

    public Animal() {
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public Animal(String name) {
        Name = name;
    }

}

然后在Controller层直接给对象赋值返回

❗Tips:这里为了方便在Controller层写的,一般都是在Service层写逻辑,我们这仅仅是为了方便演示哈

Controller代码清单

@RestController
public class HelloController {
    @GetMapping("json")
    public Object json(){
        Animal animal = new Animal();
        animal.setName("dog");
        return animal;
    }
}

好了,然后运行结果

我最开始猜测的是返回就是大写开头,结果翻车了

返回结果

image-20240330142716542

后面,我去网络上查询了一阵资料才给整好😅😅😅

其实上面的写法在Java中也不规范,Java中字段命名应该是小驼峰的

解决方案

我们来看下如何是如何解决的把

我们在字段上面加上一个注解就可以了

@JsonProperty("想要的字段名")

代码如下

public class Animal {
    @JsonProperty("Name")
    private String name;

    public Animal() {
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Animal(String name) {
        this.name = name;
    }

}

我们运行看结果

image-20240330143850308

变成大写了吧,这下能满足需求了,而且字段的命名也是符合Java规范的,Perfect

image-20240330143948474

原因分析

解决了后,我们来分析下原因,为什么之前那个我们直接把字段名改成大写不可以❓

我们通过Debug 源码发现

在Jackson包下的一个BeanUtil里面发现了缘由

image-20240330145309477

这段代码一看,一下就恍然大悟了

我们看看这个注释的意思(这里直接用插件翻译了下下😎😎)

image-20240330145507311

我们在简单解释下这段代码吧

protected static String legacyManglePropertyName(final String basename, final int offset)
    {
  			//这里的basename 就是我们的get方法名,我们这个案例就是 getName,offset是3(get的长度)
        final int end = basename.length();
        if (end == offset) { // empty name, nope
            return null;
        }
  			//去除get前缀后的第一个字母
        // next check: is the first character upper case? If not, return as is
        char c = basename.charAt(offset);
        char d = Character.toLowerCase(c);
        //如果 第一个字母是小写的话,直接返回
        if (c == d) {
            return basename.substring(offset);
        }
        // otherwise, lower case initial chars. Common case first, just one char
        StringBuilder sb = new StringBuilder(end - offset);
  			//这里先把第一个字母追加进来
        sb.append(d);
        int i = offset+1;
  			//这个循环的意思就是从 移除前缀(get、set、is)前缀后的第二个字母开始继续处理,如果第二个还是大写,就给转成小写追加进去,直到遇到小写的才break出循环
  		//举个例子,如果我们的字段是 NAme的话,会走到这里来,然后会被处理成 name 
        for (; i < end; ++i) {
            c = basename.charAt(i);
            d = Character.toLowerCase(c);
            if (c == d) {
                sb.append(basename, i, end);
                break;
            }
            sb.append(d);
        }
        return sb.toString();
    }

相信小伙伴们都看懂了吧,大家可以自己debug尝试下

不知道小伙伴们注意到没有,有里面还有个is前缀,大家是否回忆起了什么涅🧐

这里留个悬念,后期再讲咯,拜拜~

image-20240330152042348

福利时间到

别慌别慌,给各位家人们送个福利

尤其是爬虫的家人们可以关注下,详情见图
在这里插入图片描述

【都看到这了,点点赞点点关注呗,爱你们】😚😚

后端小知识关注引导

image-20240330155339598

💬

✨ 正在努力的小新~
💖 超级爱分享,分享各种有趣干货!
👩‍💻 提供:模拟面试 | 简历诊断 | 独家简历模板
🌈 感谢关注,关注了你就是我的超级粉丝啦!
🔒 以下内容仅对你可见~

作者:后端小知识CSDN后端领域新星创作者 | 阿里云专家博主

CSDN个人主页后端小知识

🔎GZH后端小知识

🎉欢迎关注🔎点赞👍收藏⭐️留言📝

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小叮当撩编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值