关于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、>

 

posted @ 2018-06-01 18:35  幽若梦蓝  Views(4931)  Comments(0Edit  收藏