前言:
剛轉(zhuǎn)后端沒多久,在通過RPC
調(diào)用其他組的服務(wù)的時(shí)候,其他組對接的同學(xué)說,你的入?yún)⑹怯袉栴}的,然后他把入?yún)l(fā)我,類似于下面的 json:
{
"addressMO": {
"roomNumber": "1002",
"street": "上海市徐匯區(qū)田林街道"
},
"age": 10,
"brotherMO": {
"addressMO": {
"$ref": "$.addressMO"
},
"className": "上海中學(xué)",
"name": "我是哥哥"
},
"name": "我是弟弟"
}
這個(gè)對象包含一個(gè) addressMO
和 brotherMO
以及 name
和 age
,brotherMO 中也包含了addressMO,就會導(dǎo)致 出現(xiàn)上面的 "$ref": "$.addressMO"
,這個(gè)其實(shí)表示的是引用根目錄中的 addressMO
對象。
這個(gè)例子其實(shí)是我簡化后的 demo
,為了簡單說明。其他的 對象如下:
public static class PersonMO {
private String name;
private int age;
private AddressMO addressMO;
private BrotherMO brotherMO;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public AddressMO getAddressMO() {
return addressMO;
}
public void setAddressMO(AddressMO addressMO) {
this.addressMO = addressMO;
}
public BrotherMO getBrotherMO() {
return brotherMO;
}
public void setBrotherMO(BrotherMO brotherMO) {
this.brotherMO = brotherMO;
}
}
public static class AddressMO {
private String street;
private String roomNumber;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getRoomNumber() {
return roomNumber;
}
public void setRoomNumber(String roomNumber) {
this.roomNumber = roomNumber;
}
}
public static class BrotherMO {
private String name;
private String className;
private AddressMO addressMO;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public AddressMO getAddressMO() {
return addressMO;
}
public void setAddressMO(AddressMO addressMO) {
this.addressMO = addressMO;
}
}
測試代碼如下:
@Test
public void testJSON() {
AddressMO addressMO = new AddressMO();
addressMO.setStreet("上海市徐匯區(qū)田林街道");
addressMO.setRoomNumber("1002");
BrotherMO brotherMO = new BrotherMO();
brotherMO.setName("我是哥哥");
brotherMO.setAddressMO(addressMO);
brotherMO.setClassName("上海中學(xué)");
PersonMO personMO = new PersonMO();
personMO.setName("我是弟弟");
personMO.setAge(10);
personMO.setAddressMO(addressMO);
personMO.setBrotherMO(brotherMO);
String ss = JSON.toJSONString(personMO);
System.out.println("ss ===== " +ss);
}
可以看到,對于一個(gè)對象,當(dāng)其首次出現(xiàn)時(shí),FastJson
的序列化是正常工作的,但是當(dāng)其重復(fù)出現(xiàn)時(shí),就會變?yōu)閷ο蟮囊?。這是FastJson
內(nèi)部存在一些特殊邏輯,問題產(chǎn)生的原因在于FastJson
存在循環(huán)/重復(fù)引用檢測特性,并且該特性是缺省開啟的。
實(shí)體轉(zhuǎn)化為json字符串后出現(xiàn)了$ref
字樣的東西,這是因?yàn)樵趥鬏數(shù)臄?shù)據(jù)中出現(xiàn)相同的對象時(shí),fastjson 默認(rèn)開啟引用檢測將相同的對象寫成引用的形式,引用是通過"$ref"
來表示的。
修改也很簡單,就是在 BrotherMO
中設(shè)置 AddressMO
對象是,通過 Copy AddressMO
對象的屬性就行了,如下:
就能正常輸出了,其中的 DozerBeanMapper
是開源庫,用來復(fù)制對象屬性的。文章來源:http://www.zghlxwxcb.cn/news/detail-434488.html
{
"addressMO": {
"roomNumber": "1002",
"street": "上海市徐匯區(qū)田林街道"
},
"age": 10,
"brotherMO": {
"addressMO": {
"roomNumber": "1002",
"street": "上海市徐匯區(qū)田林街道"
},
"className": "上海中學(xué)",
"name": "我是哥哥"
},
"name": "我是弟弟"
}
其實(shí)不改也是沒問題的,通過反序列化出來的 PersonMO
對象都是正常的。
剛開始,其他同事跟我說的時(shí)候我是很懵逼的,完全不知道,因?yàn)槲艺{(diào)用他的服務(wù)之前是加了日志的,都是正常的,但是同事說的是這個(gè)服務(wù)上線2年多了,肯定不是他們的問題,哈哈,然后 google 了下,記錄下,怕自己會忘記。文章來源地址http://www.zghlxwxcb.cn/news/detail-434488.html
到了這里,關(guān)于FastJson序列化導(dǎo)致的 “$ref“的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!