国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - jackson序列化和反序列化的應用實踐指南

jackson序列化和反序列化的應用實踐指南

2020-09-15 00:42zhouweixin Java教程

這篇文章主要給大家介紹了關于jackson序列化和反序列化的應用實踐指南,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

源碼地址:https://github.com/zhouweixin/serializable

1 相關概念

序列化: 把對象轉換為字節序列的過程稱為對象的序列化

反序列化: 把字節序列恢復為對象的過程稱為對象的反序列化

2 序列化的作用

用于把內存中的對象狀態保存到一個文件中或者數據庫中

用于網絡傳送對象

用于遠程調用傳輸對象

3 準備序列化對象

準備了兩個類, 教師類和學生類, 其中一個學生只有一個教師

這里省略了構造方法和setter, getter方法

Teacher.java

?
1
2
3
4
public class Teacher {
 private String name;
 private Integer age;
}

Student.java

?
1
2
3
4
5
6
7
8
9
10
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public enum Sex {
 MALE("男"), FEMALE("女");
 
 private String name;
 
 Sex(String name) {
 this.name = name;
 }
 
 public String getName() {
 return name;
 }
}

4 引入jackson依賴

本示例是基于gradle的, 從maven中心倉庫中選擇了2.11.2版本的jackson-databind

?
1
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.2'

5 序列化與格式化輸出

5.1 流程

首先需要有一個待序列化對象, 本例中的student對象

創建一個對象映射器, jackson包下的ObjectMapper

調用序列化函數, 本例中的writeValueAsString, 將對象轉為字符串, 便于展示

5.2 代碼

?
1
2
3
4
5
6
7
8
9
10
11
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<Student> 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 結果

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[ {
 "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 分析

示例中調用了方法writerWithDefaultPrettyPrinter, 美化了json的格式

否則將打印

?
1
[{"name":"小明","age":18,"sex":"MALE","fatherName":"王富貴","bornTime":1599997061097,"teacher":{"name":"李老師","age":40}},{"name":"小花","age":16,"sex":"FEMALE","fatherName":"錢很多","bornTime":1599997061097,"teacher":{"name":"趙老師","age":38}}]

6 自定義序列化的名字

6.1 場景

假如需要將序列化的json由駝峰命名修改為下劃線命名, 如fatherName修改為father_name

只需要在字段fatherName上用注解JsonProperty配置

6.2 示例代碼

?
1
2
3
4
@JsonProperty("father_name")
private String fatherName;
@JsonProperty("born_time")
private Date bornTime;

6.3 示例結果

[ {
  "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格式設置

當前bornTime的格式為unix時間戮, 可讀性非常差

現修改為yyyy-MM-dd HH:mm:ss

并設置時區為東八區

示例代碼

?
1
2
3
@JsonProperty("born_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date bornTime;

結果

[ {
  "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設置為中文

只需要為Sex添加一個方法getOrdinal, 并添加注解JsonValue即可

示例代碼

?
1
2
3
4
@JsonValue
public String getOrdinal() {
 return name;
}

示例結果

[ {
  "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設置為序號

有些場景喜歡用0和1等序號設置男女, 即枚舉的序號: 0表示男, 1表示女

此時需要修改Set的getOrdinal方法

  1. 修改返回值類型為int
  2. 調用父類的getOrdinal方法

示例代碼

?
1
2
3
4
@JsonValue
public int getOrdinal() {
 return super.ordinal();
}

示例結果

[ {
  "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 拍平嵌套類型

場景

如前面提到的結果所示, teacher的兩個屬性并不在student的第一層,
有時可能會更深的層次, 使用起來不太友好

如何用teacher_name和teacher_age兩個屬性代替teacher呢?

  1. 在Student的teacher屬性上添加注解JsonUnwrapped, 意為不包裹
  2. 在Teacher的屬性上利用注解JsonProperty重命名

示例代碼

Student.java

?
1
2
@JsonUnwrapped
private Teacher teacher;

Teacher.java

?
1
2
3
4
@JsonProperty("teacher_name")
private String name;
@JsonProperty("teacher_age")
private Integer age;

示例結果

[ {
  "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 場景

假如需要將年齡調整為理論學齡, 即將年齡減去7, 得到理論學齡, 如何操作呢?

創建自定義年齡序列化器AgeSerializer, 繼承StdSerializer<>

  1. 創建AgeSerializer的構造方法
  2. 重寫serialize函數

利用注解修指定Student屬性age的序列化器AgeSerializer

9.2 示例代碼

AgeSerializer.java

?
1
2
3
4
5
6
7
8
9
10
public class AgeSerializer extends StdSerializer<Integer> {
 protected AgeSerializer() {
 super(Integer.class);
 }
 
 @Override
 public void serialize(Integer value, JsonGenerator gen, SerializerProvider provider) throws IOException {
 gen.writeNumber(value - 7);
 }
}

Student.java

?
1
2
@JsonSerialize(using = AgeSerializer.class)
private Integer age;

9.3 示例結果

[ {
  "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 流程

首先需要有序列化好的數據, 可以是string, byte[], 文件二進制等

創建一個對象映射器, jackson包下的ObjectMapper

調用反序列化函數, 本例中的readValue, 將字符串轉為對象

10.2 反序列化對象數據

示例代碼

?
1
2
3
4
5
6
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);
}

示例結果

Student{name='小明', age=11, sex=MALE, fatherName='王富貴', bornTime=Sun Sep 13 20:46:10 CST 2020, teacher=Teacher{name='李老師', age=40}}

分析

為了便于打印對象數據, 重寫了Student和Teacher的toString方法

從數據中可以看出, age的結果是錯誤的, 原因在于之前自定義的序列化器將年齡減小了7, 10.4節將會通過自定義反序列化器來解決此問題

10.3 反序列化對象數組數據

示例代碼

?
1
2
3
4
5
6
7
8
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);
 }
}

示例結果

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}}

分析

readValue的第二個參數需要傳類型, 這里推薦用數組, 不推薦用List, 具體原因筆者目前也沒花時間去研究

10.4 自定義反序列化器

從10.2節及10.3的現象中可以看出來, 僅僅自定義的序列化器會導致序列化的過程是正常的, 反序列化的過程仍然是默認邏輯, 有時候會導致意想不到的結果

遇到此場景, 可以考慮自定義反序列化器

  1. 創建自定義反序列化器AgeDeserializer, 繼承StdDeserializer<>
  2. 重寫deserialize方法
  3. 在Student的age屬性上添加注解JsonDeserialize, 并指定反序列化器AgeDeserializer

示例代碼

AgeDeserializer.java

?
1
2
3
4
5
6
public class AgeDeserializer extends JsonDeserializer<Integer> {
 @Override
 public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
 return p.getIntValue() + 7;
 }
}

Student.java

?
1
2
3
@JsonSerialize(using = AgeSerializer.class)
@JsonDeserialize(using = AgeDeserializer.class)
private Integer age;

示例結果

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

該注解使用在實體類上, 格式@JsonInclude(value = JsonInclude.Include.NON_DEFAULT)

其中, Include有7種參數, 功能對比如下

 

參數 功能 備注
Include.ALWAYS 屬性總是序列化(需要有get方法) 默認值
Include.NON_DEFAULT 屬性為默認值不序列化 如: int:0, bool:false
Include.NON_EMPTY 屬性為空("")或null不序列化  
Include.NON_NULL 屬性為null不序列化  
Include.CUSTOM    
Include.USE_DEFAULTS    
Include.NON_ABSENT    

 

代碼示例

Student.java

?
1
2
@JsonInclude(value = JsonInclude.Include.NON_DEFAULT)
public class Student {
?
1
2
3
4
5
6
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
}

分析

當屬性為默認值, 即零值時, 不序列化

常見的零值:

  1. int: 0
  2. bool: false,
  3. String: null

12 注解Transient

13 注解JsonIgnore

總結

到此這篇關于jackson序列化和反序列化的應用實踐指南的文章就介紹到這了,更多相關jackson序列化和反序列化內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/zhouweixin/p/13663422.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲免费视频大全 | 国产中文视频 | 免费视频成人国产精品网站 | 噜噜噜噜狠狠狠7777视频 | 久久久久久99 | 免费观看视频毛片 | 中文字幕影院 | 国产乱码久久久久久一区二区 | 亚洲不卡视频 | 最近中文字幕免费观看 | 欧美日韩在线免费观看 | 影音先锋男 | 黄色三级视频 | 一区二区三区欧美 | 久久精品国产一区二区电影 | 国户精品久久久久久久久久久不卡 | 综合久久99| 亚洲精品片 | 免费成人在线视频网站 | 夜夜av | 亚洲精品免费播放 | 国产最好的精华液网站 | 国外爱爱视频 | 五月婷婷激情网 | 成人精品网站在线观看 | 国产在线精品一区二区三区 | 亚洲www啪成人一区二区 | 国产一区二区三区不卡在线观看 | 中文字幕一二三区 | 天天射天天干 | 欧美视频在线一区 | 久久久久久中文字幕 | 美女福利网站 | 黄色大片网站 | 99久久精品免费看国产一区二区三区 | 亚洲色综合| 午夜精品电影 | 日韩精品视频久久 | 99re国产精品视频 | 久久精品国产亚洲 | 中文字幕在线观看 |