jackson驼峰转下划线注解_jackson序列化与反序列化的应用实践
作者 | zhouweixin
來源 | urlify.cn/iEbiAz
66套java從入門到精通實戰課程分享
1 相關概念
2 序列化的作用
3 準備序列化對象
準備了兩個類, 教師類和學生類, 其中一個學生只有一個教師
這里省略了構造方法和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中心倉庫中選擇了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 結果
[?{??"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 場景
假如需要將序列化的json由駝峰命名修改為下劃線命名, 如fatherName修改為father_name
只需要在字段fatherName上用注解JsonProperty配置
6.2 示例代碼
@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
并設置時區為東八區
示例代碼
@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即可
示例代碼
@JsonValuepublic?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方法
示例代碼
@JsonValuepublic?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呢?
示例代碼
Student.java
@JsonUnwrappedprivate?Teacher?teacher;Teacher.java
@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, 得到理論學齡, 如何操作呢?
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 示例結果
[?{??"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 反序列化對象數據
示例代碼
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}}分析
10.3 反序列化對象數組數據
示例代碼
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}}分析
10.4 自定義反序列化器
從10.2節及10.3的現象中可以看出來, 僅僅自定義的序列化器會導致序列化的過程是正常的, 反序列化的過程仍然是默認邏輯, 有時候會導致意想不到的結果
遇到此場景, 可以考慮自定義反序列化器
示例代碼
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;示例結果
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: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
該注解為屬性注解, 表示忽略當前屬性, 如下所示, 表示忽略name字段
@JsonIgnoreprivate?String?name;@JsonIgnoreprivate?String?name;總結
以上是生活随笔為你收集整理的jackson驼峰转下划线注解_jackson序列化与反序列化的应用实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 2897(威佐夫博奕变形)
- 下一篇: Java代码性能优化技巧