問題描述
在開發過程中,由於接口文檔的描述,要求json字符串的key首字母為大寫,而java 的規範要求在定義bean的時候,成員屬性是首字母小寫的駝峰格式,java的基本規範一定要遵守,否則會出現一些難以發現解決的基礎問題,例如本文中提到的,fastjson轉換json字符串key首字母大寫的問題。
根本原因: java 的內省機制
內省(Introspector)是Java 語言對Bean類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設置新的值。通過 getName/setName 來訪問 name 屬性,這就是默認的規則。
一個類被當作javaBean使用時,JavaBean的屬性是根據方法名推斷出來的,它根本看不到java類內部的成員變量,通過去掉set方法前綴,然後取剩餘部分,如果剩餘部分的第二個字母是小寫的,則把剩餘部分的首字母改成小寫。
參考:http://blog.csdn.net/hahalzb/article/details/5972421
如何解決
在使用fastjson的時候,一般默認對像轉換成的字符串key的首字母是小寫的,而json字符串轉換成java bean對象的時候,json字符串怎麼寫的,封裝javabean的時候就要怎麼寫,這樣才能成功set值給javabean。如果需要將javabean轉換json字符串時key的首字母大寫可以使用fastjson 的註解 @JSONField,例如:
UserSynInfo {
/**
* 用戶Id
*
* 作為更新表的主鍵使用
*/
)
private Long userId;
/**
* 用戶暱稱
*/
)
private String nickName;
/**
* 用戶的NetId
*/
)
private Integer netId;
/**
* 用戶加入家庭時間,時間格式為標準時間戳格式,如2016-03-23 11:43:07
*/
)
private Date createTime;
/**
* 全同步不需要,單條同步需要
*/
)
private String sN;
/**
* 更新時間,時間格式為標準時間戳格式,如2016-03-23 11:43:07
*/
)
private String updateTime;
getUserId() {
return userId;
}
setUserId(Long userId) {
this.userId = userId;
}
getNickName() {
return nickName;
}
setNickName(String nickName) {
this.nickName = nickName;
}
getNetId() {
return netId;
}
setNetId(Integer netId) {
this.netId = netId;
}
getCreateTime() {
return createTime;
}
setCreateTime(Date createTime) {
this.createTime = createTime;
}
getUpdateTime() {
return updateTime;
}
setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
getsN() {
return sN;
}
setsN(String sN) {
this.sN = sN;
}
}
注意
在使用註解之前,一定要檢查自己封裝的成員屬性的規則是否符合java的基本規範,首字母小寫的駝峰格式,否則註解不會生效,不生效的原因,仍然是java的內省機制導致的。
這樣在轉換的時候就會發現:
{
",
"123,
",
",
"10061
}
這樣的註解寫法不僅僅會在普通的對象轉換的時候生效,還可以在spring中生效。
當然,解決json字符串key首字母大寫的方式還可以正常定義javabean,將成員屬性定義成首字母大寫的(雖然不符合javabean的規範),然後使用google的gson,可以將javabean封裝的成員屬性原封不動的轉換成json字符串。