写在之前
相信大家在项目中不少接触微服务化,而说到微服务化,就不得不说到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、>