我在使用protobuf时被驼峰命名坑了

2,456 阅读3分钟

问题描述

事情是这样的,这两天在做一个前后端分离的项目,通过protobuf (protobuf是什么?)定义接口。

项目规范定义的字段是蛇形的,像下面这种:

user_id

然而,当我用protoc生成Java端的代码时,以JSON形式返回结果怎么也不对,仔细看了下才发现,上面的user_id被转为驼峰命名,如下所示

userId

前后端字段名不同,当然就对接不了。

解决过程

一开始我想这应该不是是什么大问题,像mybatis什么的都有对如@TableId这样的注解来指定字段名。

像这种网上应该有直接分享吧,那就搜吧。

半个小时后,意识到了问题的不对劲。

起初觉得可能是自己描述有问题,搜索引擎搜索出来的都没有提到如何不将蛇形字段转化为驼峰字段,看了好几篇教学文档都没有。

难道是遇到这个问题的猿们不多导致不见解决方案?得,还是翻官方文档吧。

从GitHub上的protobuf项目中找到了java版本的说明文档,翻到Field那一块,看到这样一段话:

Screenshot_20220807_174215_com.tencent.mobileqq_e.jpg

主要看第二段:

Note that method names always use camel-case naming, even if the field name in the .proto file uses lower-case with underscores (as it should).

翻译一下就是: 注意方法名(其实从下文看也包括字段名)总是使用驼峰命名,即使在 .proto文件中使用的是蛇形命名,这本应如此。

好吧,我知道驼峰命名是Java中良好的命名规范,但是我们这边的规范是要蛇形命名...

8RJ$LBTPTBLDT`6WQLX{F6S.jpg

最终解决

既然官方是这么规范的,那肯定没办法直接从添加参数的角度上下手了,我想了几个角度解决:

  • protobuf是开源的,只需要修改一下源代码即可。但是问题是,本菜鸡大三在github是翻了一下源代码,使用的语言是c++,并且主要使用的是bazel,限于只在大一课上的c++水平,遂放弃。

  • 自己写一个小程序,读取.proto文件,将.class文件中的所有字段名修改为正确的名字。可行性很高,然而达成完善的版本似乎要花的时间也不少(还是先鸽着吧)。

  • 使用IDEA中强大的Ctrl+R键,手动将所有的驼峰命名转为蛇形命名。一开始我是想这样偷懒的,但是这样会导致大量的代码可读性降低,如setUserId变为setuser_id,于是不选择。

  • 在将对象转为JSON串的时我使用的是

    JsonFormat.printer().print(obj)
    

    在该方法中可以添加参数preservingProtoFieldNames()生成蛇形的JSON串

    responseJson=JsonFormat.printer().preservingProtoFieldNames().print(obj);
    

    这种方法牺牲了一定的性能用于转化字符串,但是对于我目前着手的项目来说是可以接受的,因此采取这种方法(最优应该还是1或2)。

    完结撒花~

QQ图片20220807184129.jpg

(文章如有不足望大佬指出,学生党可能遗漏一些信息)