關於JSON反序列化與序列化名稱問題的一點小經驗


寫在之前

相信大家在項目中不少接觸微服務化,而說到微服務化,就不得不說到restful接口,而說到restful接口,就不得不說其規范格式json字符串,而談到json字符串,就不得不提一下java的序列化與反序列化。沒錯,我們今天的主題就是JSON字符串的反序列化與序列化,哈哈,不要慌不要躁,慢慢看。

 

場景需求

有A、B、C三個API,A調B並且POST請求發送json字符串{"candidate-id":"1234343","overall-score":"85","create-date":"2018-06-01"},B接收該請求要將該字符串反序列化轉為對象,然后B調C並且發送POST請求(剛才的對象作為請求參數的一部分),這個時候需要序列化剛才的對象,C要求的格式是{"candidateId":"1234343","overallScore":"85","createDate":"2018-06-01"}。總結一下,就是對同一個對象的序列化和反序列化要求key不同

 

初探@JsonProperty

開始只是考慮到反序列化的key對不上,經過一番查詢資料,發現@JsonProperty這個注解,剛好能滿足我的需求,將不規則id的json字符串轉化我需要的對象。只要將@JsonProperty(value = "irregular-name")加到類成員頭部就好了,jackson Json反序列化的時候會調用該注解進行key匹配。但是當我對該對象進行序列化的時候發現,並不能滿足我的需求,序列化之后的key也變成了我定義的不規則的key。

經過一系列的騷操作,我又嘗試了一下@JsonProperty(value = "irregular-name",access = JsonProperty.Access.READ_ONLY),也就是加上access這個屬性,最后發現也不行,查了一下,這個是控制該成員是否允許序列化和是否允許反序列化的。有興趣的小伙伴可以嘗試一下,做做實例,看看報,喝喝茶,水水群什么的,啊,扯遠了,嘻嘻...

 

怎么辦呢

很慌啊,我還不信了,我不想新建對象進行重新賦值,內容都是一樣的,感覺不爽啊。程序員靠天靠地不如靠自己靠谷歌,沒錯就是它讓我發現了同樣的需求(當然,如果有時間的話,深究一下原理也是很好的,不只停留在應用上,奮斗.gif),這里mark一下jackson json 序列化與反序列化時json中字段名稱問題。該博主的場景剛好和上面描述的場景相反,有興趣的可以點進去看看,也可以接着看我的實例,也可以兩者做一下對比。筆者在這里提煉了一下: 實體bean的get方法對應序列化,而set方法則對應反序列化。也就是jackson在進行序列化的時候調用的是get方法,而反序列化的時候調用的是set方法。

 

我的代碼實例

1、創建我的實體bean

 1 package com.yrml.singleton.bean;
 2 
 3 import com.fasterxml.jackson.annotation.JsonProperty;
 4 
 5 /**
 6  * 我的實體bean
 7  *
 8  * @author zhaohui.tan
 9  */
10 public class RequestBody {
11 
12   private String candidateId;
13 
14   private String overallScore;
15 
16   private String createDate;
17 
18 
19   @JsonProperty("candidateId")            //序列化的時候要求,規則的名稱 20   public String getCandidateId() {
21     return candidateId;
22   }
23 
24   @JsonProperty(value = "candidate-id")   //反序列化的時候key名不規則 25   public void setCandidateId(final String candidateId) {
26     this.candidateId = candidateId;
27   }
28 
29   @JsonProperty("overallScore")
30   public String getOverallScore() {
31     return overallScore;
32   }
33 
34   @JsonProperty(value = "overall-score")
35   public void setOverallScore(final String overallScore) {
36     this.overallScore = overallScore;
37   }
38 
39   @JsonProperty("createDate")
40   public String getCreateDate() {
41     return createDate;
42   }
43 
44   @JsonProperty("create-date")
45   public void setCreateDate(String createDate) {
46     this.createDate = createDate;
47   }
48 
49 }

2、main測試

 1 public class MyTest {
 2 
 3     public static void main(String[] args) {
 4 
 5         String json1 = "{\"candidate-id\":\"IA_284573557_usug\", \"overall-score\":\"86\", \"create-date\":\"2018-06-01\"}";
 6         RequestBody msg1 = JsonUtil.fromJson(json1, RequestBody.class);
 7         System.out.println("msg:" + msg1);
 8 
 9         String result1 = JsonUtil.toJsonString(msg1);
10         System.out.println("result:" + result1);
11 
12     }
13 }

3、測試結果

 1 msg:com.yrml.singleton.bean.RequestBody@4df50bcc 2 result:{"candidateId":"IA_284573557_usug","overallScore":"86","createDate":"2018-06-01"} 

4、這里需要注意一點,我的實體bean中get方法的名稱還是正規的,也就是我們普通生成getter、setter方法時候的名稱。但是這兒有個問題,通過普通Java類測試的時候是沒有問題的,也就是上面的實例所示。但是,當在HTTP請求的時候,就會報錯。這個時候需要經get方法的名稱該變一下。如下所示:【這個原理倒沒有深究了,有興趣的小伙伴可以研究一下】

 1  @JsonProperty("candidateId")
 2   public String getCandidate_Id() {
 3     return candidateId;
 4   }
 5 
 6   @JsonProperty("overallScore")
 7   public String getOverall_Score() {
 8     return overallScore;
 9   }
10 
11   @JsonProperty("createDate")
12   public String getCreate_Date() {
13     return createDate;

 

寫在最后

書山有路勤為徑、學海無害苦作舟. <手動Mrak、>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM