Lombok首字母小寫,第二個字母大寫的問題

一、問題描述

最近在和前端對接接口的時候,發(fā)現(xiàn)后端接口返回給前端的一個字段大小寫有問題,具體如下。

使用的開發(fā)框架及版本:

框架:SpringMVC;
Lombok版本:1.18.12;

對象簡化后如下:

@Data
public class MobileInfo {
    private String iPhone;
}

預(yù)期返回結(jié)果:iPhone,實際返回結(jié)果:iphone

也就是說SpringMVC環(huán)境下,使用Lombok注解@Data之后,返回給前端的是iphone,而不是我們預(yù)期中的iPhone。

二、原因

針對首字母小寫,第二個字母大寫的這種駝峰命名時,使用@Data注解生成的getter和setter方法分別是:

public String getIPhone() {
    return iPhone;
}

public void setIPhone(String iPhone) {
    this.iPhone = iPhone;
}

而正常場景下及Spring中對象的getter和setter方法應(yīng)該是:

public String getiPhone() {
    return iPhone;
}

public void setiPhone(String iPhone) {
    this.iPhone = iPhone;
}

也就是說Lombok與Spring針對這種首字母小寫,第二個字母大寫的對象的解析是不同的,而這也就自然而然影響到默認的Jackson的解析,導(dǎo)致返回給前端的屬性名稱不是我們預(yù)期中的名稱。

2.1 Lombok問題

其實,針對這個問題,多年前就有人已經(jīng)在lombok的github提出過對應(yīng)的issue,參考:

https://github.com/projectlombok/lombok/issues/757

其實,無論是Lombok還是Spring,在處理對象的時候總會有一個API規(guī)范進行參考的,這個規(guī)范一般就是JavaBeans API的規(guī)范。而針對這個問題,Lombok的官方回復(fù)是:

JavaBeans的規(guī)范就是這樣的,Lombok只是遵循這個規(guī)范而已,并且不應(yīng)該使用首字母小寫,第二個字母大寫這樣的命名規(guī)則,而Spring的處理方式才是沒有遵循JavaBean的規(guī)范。除非Oracle官方推薦如此或者大家都是這樣處理的化,Lombok才會進行修改。

也就是說,Lombok認為,JavaBeans的規(guī)范就是這么定義的,而針對JavaBean的規(guī)范,Spring和Lombok選擇了不同的實現(xiàn)方式:

  • Spring,Jackson針對get/set的生成方式,和我們使用 IDEA 編譯器自動生成get/set的方式是相同的,都是諸如getiPhone()的形式。
  • Lombok,針對get/set的生成方式,是getIPhone()的形式。

那么,針對JavaBeans規(guī)范的定義,到底是Spring的這種方式正確呢,還是Lombok的解析方式正確呢?

2.2 JavaBeans API規(guī)范

Lombok官方回復(fù)的JavaBeans API規(guī)范,是Sun 1997年的API規(guī)范文檔:

https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/

根據(jù)這個文檔,我去stackoverflow上搜了一下,最接近這個問題的描述應(yīng)該是:8.8 Capitalization of inferred names

其實根據(jù)JavaBeans的描述,是沒有具體說明針對我們文中這個問題,首字母小寫,第二個字母大寫這樣的字段該如何get/set的,不過如果強行按照JavaBeans的規(guī)范來的話,那這個其實應(yīng)該是:

public String getiPhone() { return iPhone;}
public void setiPhone(String iPhone) { this.iPhone = iPhone;}

那如果從這點上來說的話,其實Lombok的說法就不太恰當(dāng)?shù)牧恕?/p>

不過還有一種方式,就是如果站在Java中方法命名的角度上來說的話,也就是:Defing Methods - Naming a Method
那么,正確的命名方式應(yīng)該是:

public String getIPhone() { return iPhone;}
public void setIPhone(String iPhone) { this.iPhone = iPhone;}

那么站到這個角度的話,Spring的方式又是不太恰當(dāng)?shù)牧恕?/p>

不過,總的來說,Lombok和Spring他們各自的實現(xiàn)本身沒啥問題,只是針對javaBean的規(guī)范,各自選擇了不同的實現(xiàn)策咯而已。

大家有興趣的可以看下stackoverflow上的討論及Lombok的回復(fù):
https://stackoverflow.com/questions/2948083/naming-convention-for-getters-setters-in-java/49348966#49348966
https://github.com/projectlombok/lombok/issues/504

三、解決方式

知道了原因,其實解決起來也非常簡單了,就是針對這種對象,手動生成get和set方法即可,或者使用編譯器自動生成的,也就是如下:

public String getiPhone() {
    return iPhone;
}

public void setiPhone(String iPhone) {
    this.iPhone = iPhone;
}

當(dāng)然為了避免這種問題發(fā)生,還有一種更簡單的方式,就是命名的時候,不要使用諸如xXXXX這種格式的命名,使用正常的命名方式,比如indexX這種形式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容