Lombok的坑@Data,后台返回给前端json字段的大小写驼峰命名问题

以前在处理前端请求的实体类的时候,都是用Lombok的@Data注解对实体类进行getter、setter以及toString的声名,今天处理实体类的时候,发现生成的setter方法和Java Bean的命名规则不一致。(@Data的作用是为我们定义的字段添加Lombok的@ToString、@EqualsAndHashCode、 @Getter方法、@RequiredArgsConstructor 和 为非final字段添加@Setter)

我要生成getter、setter的字段是:

    private Integer cId;

在我使用@Data时生成的代码和实际要生成的代码比较如下:

 
  1. //@Data生成的setter方法
  2. setCId;
  3. //实际需要的setter方法
  4. setcId()
 

Java Bean的4种命名特殊规范中有一种情况:如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。

字段的首字母大小写发生了变化。这个变化导致了,我在使用@Data注解生成的getter方法得到的属性值是"cid",而实际上我需要的属性值为"cId",这也就导致了我返回给前端的数据,前端无法识别,从而出错。


前置知识点

1、JavaBean的生成规则

JavaBean定义:一种JAVA语言写成的可重用组件,通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。

JavaBean getter/setter命名规范[特例]

一般JavaBean属性以小写字母开头,驼峰命名格式,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。例如:属性名为userName,其对应的getter/setter 方法是 getUserName/setUserName。

但是,还有一些特殊情况:

  1. 如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 的后部分,就是说大小写不变。例如属性名为uName,方法是getuName/setuName。
  2. 如果属性名的前两个字母是大写(一般的专有名词和缩略词都会大写),也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为URL,方法是getURL/setURL。
  3. 如果属性名的首字母大写,也是属性名直接用作 getter/setter 方法中 get/set 的后部分。例如属性名为Name,方法是getName/setName,这种是最糟糕的情况,会找不到属性出错,因为默认的属性名是name。
  4. 如果属性名以"is"开头,则getter方法会省掉get,set方法会去掉is。例如属性名为isOK,方法是isOK/setOK。需要注意的是有些开发工具自动生成的getter/setter方法,并没有考虑到上面所说的特例情况,会导致bug的产生。

2、Lombok的生成规则

一句话get/set都会将首字母大写

 
  1. @Data
  2. public class JavaBean{
  3. private Integer cId;
  4. //lombok帮你生成的
  5. public Integer getCId() {
  6. return cId;
  7. }
  8. //lombok帮你生成的
  9. public void setCId(Integer cId) {
  10. this.cId = cId;
  11. }
  12. //最后通过lombok得到cid
  13. }
 

cId最后通过lombok的getter最后得到的cid(但原理我确实无法理解)


如何解决问题

前后端字母大小写不一致问题归根结底就是你在项目中使用lombok了原因。解决方案有两个:

方法一: 去掉lombok中的@Data注解,手动导入get/set方法

方法二:在JavaBean中通过@JsonProperty强制定义

 
  1. @JsonProperty("cId")
  2. //本来得到的是cid,通过这个注解可以强制得到cId
  3. private Interger cId;
 

方法三:注意命名方式,在定义JavaBean的属性名时,应该尽量避免属性名的头两个字母中任意一个为大写以及属性名以"is"开头。

posted @ 2025-01-17 12:22  CharyGao  阅读(129)  评论(0)    收藏  举报