jackson 序列化_jackson序列化与反序列化的应用实践
作者 | zhouweixin
來源 | urlify.cn/iEbiAz
66套java從入門到精通實(shí)戰(zhàn)課程分享
1 相關(guān)概念
2 序列化的作用
3 準(zhǔn)備序列化對(duì)象
準(zhǔn)備了兩個(gè)類, 教師類和學(xué)生類, 其中一個(gè)學(xué)生只有一個(gè)教師
這里省略了構(gòu)造方法和setter, getter方法
Teacher.java
public?class?Teacher?{????private?String?name;????private?Integer?age;}Student.java
package?org.zwx;public?class?Student?{????private?String?name;????private?Integer?age;????private?Sex?sex;????private?String?fatherName;????private?Date?bornTime;????private?Teacher?teacher;}Sex.java
public?enum?Sex?{????MALE("男"),?FEMALE("女");????private?String?name;????????Sex(String?name)?{????????this.name?=?name;????}????public?String?getName()?{????????return?name;????}}4 引入jackson依賴
本示例是基于gradle的, 從maven中心倉(cāng)庫中選擇了2.11.2版本的jackson-databind
compile?group:?'com.fasterxml.jackson.core',?name:?'jackson-databind',?version:?'2.11.2'5 序列化與格式化輸出
5.1 流程
5.2 代碼
public?void?testSerializable()?throws?IOException?{????Student?student1?=?new?Student("小明",?18,?Sex.MALE,?"王富貴",?new?Date(),?new?Teacher("李老師",?40));????Student?student2?=?new?Student("小花",?16,?Sex.FEMALE,?"錢很多",?new?Date(),?new?Teacher("趙老師",?38));????List?students?=?new?ArrayList<>();????students.add(student1);????students.add(student2);????ObjectMapper?mapper?=?new?ObjectMapper();????String?s?=?mapper.writerWithDefaultPrettyPrinter().writeValueAsString(students);????System.out.println(s);}5.3 結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?"MALE",??"fatherName"?:?"王富貴",??"bornTime"?:?1599996926917,??"teacher"?:?{????"name"?:?"李老師",????"age"?:?40??}},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?"FEMALE",??"fatherName"?:?"錢很多",??"bornTime"?:?1599996926917,??"teacher"?:?{????"name"?:?"趙老師",????"age"?:?38??}}?]5.4 分析
6 自定義序列化的名字
6.1 場(chǎng)景
假如需要將序列化的json由駝峰命名修改為下劃線命名, 如fatherName修改為father_name
只需要在字段fatherName上用注解JsonProperty配置
6.2 示例代碼
@JsonProperty("father_name")private?String?fatherName;@JsonProperty("born_time")private?Date?bornTime;6.3 示例結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?"MALE",??"teacher"?:?{????"name"?:?"李老師",????"age"?:?40??},??"father_name"?:?"王富貴",??"born_time"?:?1599997157609},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?"FEMALE",??"teacher"?:?{????"name"?:?"趙老師",????"age"?:?38??},??"father_name"?:?"錢很多",??"born_time"?:?1599997157610}?]7 自定義輸出格式
7.1 bornTime格式設(shè)置
當(dāng)前bornTime的格式為unix時(shí)間戮, 可讀性非常差
現(xiàn)修改為yyyy-MM-dd HH:mm:ss
并設(shè)置時(shí)區(qū)為東八區(qū)
示例代碼
@JsonProperty("born_time")@JsonFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss",?timezone?=?"GMT+8")private?Date?bornTime;結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?"MALE",??"teacher"?:?{????"name"?:?"李老師",????"age"?:?40??},??"father_name"?:?"王富貴",??"born_time"?:?"2020-09-13?19:50:47"},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?"FEMALE",??"teacher"?:?{????"name"?:?"趙老師",????"age"?:?38??},??"father_name"?:?"錢很多",??"born_time"?:?"2020-09-13?19:50:47"}?]7.2 sex設(shè)置為中文
只需要為Sex添加一個(gè)方法getOrdinal, 并添加注解JsonValue即可
示例代碼
@JsonValuepublic?String?getOrdinal()?{????return?name;}示例結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?"男",??"teacher"?:?{????"name"?:?"李老師",????"age"?:?40??},??"father_name"?:?"王富貴",??"born_time"?:?"2020-09-13?19:57:47"},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?"女",??"teacher"?:?{????"name"?:?"趙老師",????"age"?:?38??},??"father_name"?:?"錢很多",??"born_time"?:?"2020-09-13?19:57:47"}?]7.3 sex設(shè)置為序號(hào)
有些場(chǎng)景喜歡用0和1等序號(hào)設(shè)置男女, 即枚舉的序號(hào): 0表示男, 1表示女
此時(shí)需要修改Set的getOrdinal方法
示例代碼
@JsonValuepublic?int?getOrdinal()?{????return?super.ordinal();}示例結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?0,??"teacher"?:?{????"name"?:?"李老師",????"age"?:?40??},??"father_name"?:?"王富貴",??"born_time"?:?"2020-09-13?20:01:44"},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?1,??"teacher"?:?{????"name"?:?"趙老師",????"age"?:?38??},??"father_name"?:?"錢很多",??"born_time"?:?"2020-09-13?20:01:44"}?]8 拍平嵌套類型
場(chǎng)景
如前面提到的結(jié)果所示, teacher的兩個(gè)屬性并不在student的第一層,
有時(shí)可能會(huì)更深的層次, 使用起來不太友好
如何用teacher_name和teacher_age兩個(gè)屬性代替teacher呢?
示例代碼
Student.java
@JsonUnwrappedprivate?Teacher?teacher;Teacher.java
@JsonProperty("teacher_name")private?String?name;@JsonProperty("teacher_age")private?Integer?age;示例結(jié)果
[?{??"name"?:?"小明",??"age"?:?18,??"sex"?:?0,??"teacher_name"?:?"李老師",??"teacher_age"?:?40,??"father_name"?:?"王富貴",??"born_time"?:?"2020-09-13?20:21:53"},?{??"name"?:?"小花",??"age"?:?16,??"sex"?:?1,??"teacher_name"?:?"趙老師",??"teacher_age"?:?38,??"father_name"?:?"錢很多",??"born_time"?:?"2020-09-13?20:21:53"}?]9 自定義序列化器
9.1 場(chǎng)景
假如需要將年齡調(diào)整為理論學(xué)齡, 即將年齡減去7, 得到理論學(xué)齡, 如何操作呢?
9.2 示例代碼
AgeSerializer.java
public?class?AgeSerializer?extends?StdSerializer?{????protected?AgeSerializer()?{????????super(Integer.class);????}????@Override????public?void?serialize(Integer?value,?JsonGenerator?gen,?SerializerProvider?provider)?throws?IOException?{????????gen.writeNumber(value?-?7);????}}Student.java
@JsonSerialize(using?=?AgeSerializer.class)private?Integer?age;9.3 示例結(jié)果
[?{??"name"?:?"小明",??"age"?:?11,??"sex"?:?0,??"teacher_name"?:?"李老師",??"teacher_age"?:?40,??"father_name"?:?"王富貴",??"born_time"?:?"2020-09-13?20:31:59"},?{??"name"?:?"小花",??"age"?:?9,??"sex"?:?1,??"teacher_name"?:?"趙老師",??"teacher_age"?:?38,??"father_name"?:?"錢很多",??"born_time"?:?"2020-09-13?20:31:59"}?]10 反序列化
10.1 流程
10.2 反序列化對(duì)象數(shù)據(jù)
示例代碼
public?void?testDeserializable()?throws?JsonProcessingException?{????String?s?=?"{"name":"小明","age":11,"sex":0,"teacher_name":"李老師","teacher_age":40,"father_name":"王富貴","born_time":"2020-09-13?20:46:10"}";????ObjectMapper?mapper?=?new?ObjectMapper();????Student?student?=?mapper.readValue(s,?Student.class);????System.out.println(student);}示例結(jié)果
Student{name='小明',?age=11,?sex=MALE,?fatherName='王富貴',?bornTime=Sun?Sep?13?20:46:10?CST?2020,?teacher=Teacher{name='李老師',?age=40}}分析
10.3 反序列化對(duì)象數(shù)組數(shù)據(jù)
示例代碼
public?void?testDeserializableStudents()?throws?JsonProcessingException?{????String?s?=?"[{"name":"小明","age":11,"sex":0,"teacher_name":"李老師","teacher_age":40,"father_name":"王富貴","born_time":"2020-09-13?20:51:31"},{"name":"小花","age":9,"sex":1,"teacher_name":"趙老師","teacher_age":38,"father_name":"錢很多","born_time":"2020-09-13?20:51:31"}]";????ObjectMapper?mapper?=?new?ObjectMapper();????Student[]?students?=?mapper.readValue(s,?Student[].class);????for?(Student?student?:?students)?{????????System.out.println(student);????}}示例結(jié)果
Student{name='小明',?age=11,?sex=MALE,?fatherName='王富貴',?bornTime=Sun?Sep?13?20:51:31?CST?2020,?teacher=Teacher{name='李老師',?age=40}}Student{name='小花',?age=9,?sex=FEMALE,?fatherName='錢很多',?bornTime=Sun?Sep?13?20:51:31?CST?2020,?teacher=Teacher{name='趙老師',?age=38}}分析
10.4 自定義反序列化器
從10.2節(jié)及10.3的現(xiàn)象中可以看出來, 僅僅自定義的序列化器會(huì)導(dǎo)致序列化的過程是正常的, 反序列化的過程仍然是默認(rèn)邏輯, 有時(shí)候會(huì)導(dǎo)致意想不到的結(jié)果
遇到此場(chǎng)景, 可以考慮自定義反序列化器
示例代碼
AgeDeserializer.java
public?class?AgeDeserializer?extends?JsonDeserializer?{????@Override????public?Integer?deserialize(JsonParser?p,?DeserializationContext?ctxt)?throws?IOException,?JsonProcessingException?{????????return?p.getIntValue()?+?7;????}}Student.java
@JsonSerialize(using?=?AgeSerializer.class)@JsonDeserialize(using?=?AgeDeserializer.class)private?Integer?age;示例結(jié)果
Student{name='小明',?age=18,?sex=MALE,?fatherName='王富貴',?bornTime=Sun?Sep?13?20:51:31?CST?2020,?teacher=Teacher{name='李老師',?age=40}}Student{name='小花',?age=16,?sex=FEMALE,?fatherName='錢很多',?bornTime=Sun?Sep?13?20:51:31?CST?2020,?teacher=Teacher{name='趙老師',?age=38}}11 注解JsonInclude
該注解使用在實(shí)體類上, 格式@JsonInclude(value = JsonInclude.Include.NON_DEFAULT)
其中, Include有7種參數(shù), 功能對(duì)比如下
參數(shù)功能備注Include.ALWAYS屬性總是序列化(需要有g(shù)et方法)默認(rèn)值Include.NON_DEFAULT屬性為默認(rèn)值不序列化如: int:0, bool:falseInclude.NON_EMPTY屬性為空("")或null不序列化
Include.NON_NULL屬性為null不序列化
Include.CUSTOM
Include.USE_DEFAULTS
Include.NON_ABSENT
代碼示例
Student.java
@JsonInclude(value?=?JsonInclude.Include.NON_DEFAULT)public?class?Student?{public?void?testNonDefault()?throws?IOException?{????Student?student?=?new?Student("",?0,?null,?null,?null,?null);????ObjectMapper?mapper?=?new?ObjectMapper();????String?s?=?mapper.writeValueAsString(student);????System.out.println(s);}示例輸出
{??"name"?:?"",??"age"?:?-7}分析
12 注解JsonIgnoreProperties
該注解為類注解, 配置忽略序列化和反序列化的字段名
如下所示, 忽略字段name和age
13 注解JsonIgnore
該注解為屬性注解, 表示忽略當(dāng)前屬性, 如下所示, 表示忽略name字段
@JsonIgnoreprivate?String?name;@JsonIgnoreprivate?String?name;總結(jié)
以上是生活随笔為你收集整理的jackson 序列化_jackson序列化与反序列化的应用实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: onclick 获取img 里面的id_
- 下一篇: 电脑中的管理员账户是什么意思