成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

fastjson轉(zhuǎn)換json時(shí),碰到的那些首字母大小寫轉(zhuǎn)換的坑!

tyheist / 2880人閱讀

摘要:某年某月的某一天,本汪在某個(gè)奇葩的公司,接手了某個(gè)奇葩的項(xiàng)目,遇到了一些奇葩的事情,就掉進(jìn)關(guān)于做轉(zhuǎn)換時(shí),那些關(guān)于首字符大小寫的坑。坑首字符小寫,第二個(gè)字符大寫的鍵名這個(gè)坑與相關(guān),嚴(yán)格來說,應(yīng)該是挖的坑。

某年某月的某一天,本汪在某個(gè)奇葩的公司,接手了某個(gè)奇葩的項(xiàng)目,遇到了一些奇葩的事情,就掉進(jìn)關(guān)于fastjson做bean to json轉(zhuǎn)換時(shí),那些關(guān)于首字符大小寫的坑。

這個(gè)奇葩項(xiàng)目里面,api接口定義的是天馬行空、云山霧繞,api里面的字段定義更是五花八門、千奇百怪,完全沒有規(guī)則可言,都可以開個(gè)不符合規(guī)范的案例博物館了。下面3個(gè)坑里面舉的例子,那些奇葩的名稱定義,都是在項(xiàng)目里面真實(shí)存在的,如有雷同,純屬不幸。

在api的處理過程里面,bean轉(zhuǎn)換成json時(shí),我們總是希望字段名是什么樣的,轉(zhuǎn)換成json就應(yīng)該是什么樣的,然而現(xiàn)實(shí)總是殘酷的。

坑0x01 全大寫的鍵名

這種情況在api定義里面很常見,如下:

private String TEST = “1”;
public String getTEST() { return this.TEST}

在fastjson轉(zhuǎn)換后,變成:json{ “tEST”: ”1”},與預(yù)期不符,首字母變成小寫了。

原因:
fastjson在將bean轉(zhuǎn)換為json時(shí),先取出對(duì)應(yīng)的methodName: getTEST,從methodName的第4個(gè)字符開始,取出propertyName:TEST,它默認(rèn)認(rèn)為這個(gè)propertyName的首字母是在定義getter的時(shí)候被寫成大寫的,現(xiàn)在要轉(zhuǎn)成小寫:
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
結(jié)果,正確的TEST就被轉(zhuǎn)成錯(cuò)誤的tEST了。

解決:
解決這個(gè)問題比較簡(jiǎn)單,在轉(zhuǎn)換前,多加一行代碼:
TypeUtils.compatibleWithJavaBean =true;
此時(shí),fastjson會(huì)先判斷propertyName長(zhǎng)度大于1、且頭兩個(gè)字符都是大寫時(shí),不做轉(zhuǎn)換:

if(name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){
    return name;
}

也就是說,連續(xù)大寫開頭的propertyName,在轉(zhuǎn)換時(shí),會(huì)保持原樣。

坑0x02 第一個(gè)字符大寫,第二個(gè)字符不是大寫的鍵名

按坑0x01里面講的設(shè)置TypeUtils.compatibleWithJavaBean=true后,如果有如下的鍵名,依然會(huì)出問題:

private String T_EST = “1”;
private String Test = “2”;
public String getT_EST() { return this.T_EST}
public String getTest() { return this.Test}

在fastjson轉(zhuǎn)換后,變成:{ “t_EST”: ”1”, “test”:”2”},又是一個(gè)坑。

原因:
從坑0x01的最后一段代碼可以看出,要想fastjson不改首字符,除了需要設(shè)置compatibleWithJavaBean外,propertyName的第二個(gè)字符也必須是大寫。在坑0x02這里,兩個(gè)propertyName都無法通過判斷,首字母就要被轉(zhuǎn)換成小寫了。

解決
要解決這個(gè)問題,在轉(zhuǎn)換前,必須再加一行代碼:
TypeUtils.compatibleWithFieldName = true;
Fastjson里面對(duì)應(yīng)的處理代碼如下:

if(compatibleWithFieldName){
    if(!fieldCacheMap.containsKey(propertyName)){
        String tempPropertyName = methodName.substring(fromIdx);
        return fieldCacheMap.containsKey(tempPropertyName) ? tempPropertyName : propertyName;
    }
}

fastjson在按坑0x01所述的過程處理完propertyName后,propertyName的首字符被轉(zhuǎn)換為小寫,然后會(huì)在bean的的field列表里面找一遍轉(zhuǎn)換后的名稱。如果找不到,就從methodName里面重新取get后面的字符串,然后再到field列表里面找一遍,如果找到,就用原propertyName,如果找不到就用首字符被轉(zhuǎn)換的名稱。

坑0x03 首字符小寫,第二個(gè)字符大寫的鍵名

這個(gè)坑與lombok相關(guān),嚴(yán)格來說,應(yīng)該是lombok挖的坑。
如上所述,就算你按坑0x01、0x02設(shè)置了,如果在工程里面用lombok時(shí),有如下的鍵名定義,依然要被坑:

@Getter
private String iPhone = “1”;

在fastjson轉(zhuǎn)換后,變成:{ “IPhone”: ”1” },首字符變大寫了,WTF!

原因:
Lombok在自動(dòng)生成getter的時(shí)候,會(huì)把propertyName的第一的字母改成大寫,等同如下代碼:

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

問題就出在這個(gè)轉(zhuǎn)換上,get后面緊跟的字符變成大寫了。在eclipse、idea里面,如果自動(dòng)生成代碼,get后的字符是小寫。

如前面坑0x01最后一段代碼,fastjson在處理getter時(shí),會(huì)判斷前兩個(gè)字符是不是大寫,如果是的話,就保持原樣,取到的propertyName就成了:IPhone。但是在field列表里面,對(duì)應(yīng)的propertyName是iPhone,就算開啟了compatibleWithFieldName,fastjson用從getter中解析出來的IPhone,在field列表里面也找不到對(duì)應(yīng)值,也只能保持IPhone這個(gè)名稱了。

另外,就算在屬性前用了@JSONField(name = “iPhone”)注解,因?yàn)閒astjson用從getter解析出來的propertyName找不到對(duì)應(yīng)的field,也無法讀出該field對(duì)應(yīng)的注解,這個(gè)注解也是無效的。

解決

碰到這種propertyName,就不要用lombok生成的getter/setter了,自己寫,保持首字符小寫,如:getiPhone/setiPhone,只要在代碼里面有這兩個(gè)方法,lombok就不會(huì)自動(dòng)生成,lombok是按忽略大小寫后的propertyName判斷的。

把propertyName第二個(gè)字符改成小寫,或者重新取個(gè)名字,并用@JSONField注明正確的名稱,如:

@Getter
@ JSONField(name = “iPhone”)
private String iphone = “1”;

關(guān)于lombok的這個(gè)坑,可以參考:http://xxxx.ooo/2017/using-lo...,lombok的作者也是死鴨子嘴硬,被提了n多的issue,就是不改。

以上,就是本汪在項(xiàng)目里面填坑的過程,不要問我為什么api里面的字段名稱會(huì)定義成這副模樣,本汪也不知道,汪!汪?。⊥簦。?!

關(guān)于fastjson的代碼,都在TypeUtils.computeGetters里面。
@JSONField是個(gè)好東西,不嫌麻煩的話,就都加上吧。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71572.html

相關(guān)文章

  • CodeIgniter遇到

    摘要:文件夾中的文件首字母大寫。因?yàn)樵谥形覜]有找到日期和字符串轉(zhuǎn)換和格式化的靈活方法,所以在中處理格式化的問題。獲取參數(shù)由于框架自身設(shè)計(jì)的問題,推薦盡量用方式請(qǐng)求后臺(tái)服務(wù),參數(shù)格式為格式。 1.controllers文件夾中的controller文件首字母大寫。不大寫也可以,但是環(huán)境兼容性不好,舉個(gè)例子,我開發(fā)環(huán)境在mac電腦上,文件名首字母小寫,服務(wù)可以正常訪問;但是在阿里云服務(wù)器(deb...

    andot 評(píng)論0 收藏0
  • 流暢 Python - 3. 文本與字節(jié)

    摘要:不同編碼器編碼的相同的字符,最終的字節(jié)大小可能會(huì)不同。對(duì)于和,是由于對(duì)應(yīng)編碼不能處理字符串字節(jié)導(dǎo)致的。在另外兩個(gè)規(guī)范化形式和的首字母縮略詞中,字母表示兼容性。最后是雙模,同一函數(shù)能接受字符串和字節(jié)進(jìn)行操作。 對(duì)于字符串,我們接觸得挺多的。而編碼問題,也不時(shí)令人頭疼的。 由于一開始接觸的就是 Python3,所以一些在 Python2 上的編碼上的坑我沒遇到,甚至在 Python3 上都...

    e10101 評(píng)論0 收藏0
  • 高性能JSON框架之FastJson簡(jiǎn)單使用

    摘要:前言的介紹協(xié)議使用方便,越來越流行的處理器有很多這里我介紹一下是阿里的開源框架被不少企業(yè)使用是一個(gè)極其優(yōu)秀的框架地址的特點(diǎn)數(shù)度快無論序列化和反序列化都是當(dāng)之無愧的功能強(qiáng)大支持普通類包括任意或零依賴沒有依賴其它任何類庫(kù)的簡(jiǎn)單說明對(duì)于格式字符串 1.前言 1.1.FastJson的介紹: JSON協(xié)議使用方便,越來越流行,JSON的處理器有很多,這里我介紹一下FastJson,FastJs...

    Karrdy 評(píng)論0 收藏0
  • PHP中變量、注釋、輸出

    摘要:學(xué)習(xí)第一課變量注釋輸出上圖是一段超級(jí)簡(jiǎn)單的輸出的代碼,是不是超級(jí)簡(jiǎn)單呢今天文章講的就是這幾行代碼的知識(shí)。變量可以通過變量名訪問。用來定義聲明一個(gè)變量。有返回值,總是返回。輸出格式化的字符串,有返回值,返回值是輸出的字符串的長(zhǎng)度。 來一波 Hello World,各位看官先感受下。PHP學(xué)習(xí)第一課:變量、注釋、輸出上圖是一段超級(jí)簡(jiǎn)單的輸出 Hello World 的代碼,是不是超級(jí)簡(jiǎn)單呢...

    cgh1999520 評(píng)論0 收藏0
  • PHP常用函數(shù)之字符串處理

    摘要:為數(shù)組示例說明在中將字符串替換為即可。返回其中如果的數(shù)組值比的數(shù)組值長(zhǎng),將中多出來的數(shù)組元素在中匹配的字符串替換為空串,返回。 字符串大小寫轉(zhuǎn)換 strtoupper(string $str) //把字符串全部轉(zhuǎn)換成大寫字母 strtolower(string $str) //把字符串全部轉(zhuǎn)換成小寫字母 ucfirst(string $str) //把字符串的首字母轉(zhuǎn)換成大寫 ucw...

    SwordFly 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

tyheist

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<