写在之前
相信大家在项目中不少接触微服务化,而说到微服务化,就不得不说到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;
写在最后
书山有路勤为径、学海无害苦作舟.
来源:抚顺市博远电子,如涉及版权问题请与我们联系。
TAG
软件定制,软件开发,瀚森HANSEN,辽宁,沈阳,抚顺