Jackson(3)之常用註解使用
Jackson根據它的預設方式序列化和反序列化java物件,比如:預設情況下Jackson序列化或反序列化java物件是按物件屬性進行一一匹配、返序列化json串裡不能帶特殊字元等。若根據實際需要,可以靈活的調整Jackson序列化和反序列化的規則。比如:可以設定ObjectMapper屬性(詳細請參考:ObjectMapper配置詳解 ),也可以使用Jackson的註解。常用的註解及詳細的使用方法如下:
(1)@JsonProperty註解
用於物件的屬性,把屬性的名稱在序列化或反序列化時,轉換為另外一個名稱(預設是屬性名稱)。
#示例:UserInfo序列號後birthDate在json串的名稱轉為birth_date
@Data
public class UserInfo implements Serializable {
@JsonProperty("birth_date")
private Date birthDate;
private Integer age;
private String name;
private Long id;
}
#下面json串會反序列化失敗,不識別birthDate欄位
{"birthDate":"2020-11-20 10:43:57","id":100,"age":100,"name":"小米"}
#下面json串反序列化成功
{"birth_date":"2020-11-20 10:43:57","id":100,"age":100,"name":"小米"}
(2)@JsonFormat註解
用於屬性或者Getter/Setter方法上,作用是把Date型別序列化成指定格式 和 把指定格式的時間字串反序列化成Date型別。
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthDate;
#或者放在Getter/Setter方法上(Getter或Setter上效果一樣,都能控制序列化和反序列化)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date getBirthDate(){
return birthDate;
}
注意:@JsonFormat註解和@DateTimeFormat的區別:前端請求Content-Type=application/json的post請求時,@JsonFormat規定接收的時間格式;前端表單提交時,@DateTimeFormat規定接收的時間格式。(詳細請參考:@JsonFormat和@DateTimeFormat本質區別)
(3)@JsonPropertyOrder註解
用於類的註解,指定屬性在序列化時json中的順序。(@JsonPropertyOrder註解的alphabetic屬性可用於Json串裡屬性按字母順序排列)
@JsonPropertyOrder({"birthDate", "id","age", "name"})
public class UserInfo{
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
private Date birthDate;
}
#最終序列化後,json中的順序為@JsonPropertyOrder中指定的順序。
{"birthDate":"2020-11-20 13:14:56","id":1000,"age":10,"name":"小強"}
#序列化後的json串按屬性按字母順序排列
@JsonPropertyOrder(alphabetic = true)
public class UserInfo{
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
private Date birthDate;
}
(4)@JsonCreator註解
用於構造方法,和 @JsonProperty配合使用,適用有引數的構造方法。作用就是指定反序列化時用哪個建構函式。
@Data
public class UserInfo implements Serializable {
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
private Date birthDate;
@JsonCreator //json反序列化時呼叫此建構函式
public UserInfo(@JsonProperty("name") String name) {
System.out.println("11111111111111111111111111111");
this.name = name;
}
public UserInfo() {
System.out.println("222222222222222222222222222");
}
}
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "{"birthDate":"2020-11-20 10:43:57","id":100,"age":100,"name":"小米"}";
UserInfo userInfo = mapper.readValue(jsonStr, UserInfo.class);
System.out.println(userInfo);
}
//輸出:反序列化時使用的構造器是帶@JsonCreator的構造器
11111111111111111111111111111
UserInfo(id=100, name=小米, age=100, birthDate=Fri Nov 20 18:43:57 CST 2020)
(5)@JsonIgnore註解
在Java物件序列化為json時 ,有些屬性需要過濾掉不顯示在 json中;反序列化時,即使json串中有屬性的值,也不會注入物件。
@Data
public class UserInfo implements Serializable {
private Long id;
@JsonIgnore
private String name; //name序列化 和 反序列化時會被忽略掉
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
private Date birthDate;
}
//測試類
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
UserInfo info = new UserInfo();
info.setAge(100);
info.setName("直播"); //name序列化會被忽略掉
info.setId(1000L);
info.setBirthDate(new Date());
String json = mapper.writeValueAsString(info);
System.out.println(json);
System.out.println("============================");
//name反序列化會被忽略掉
String json = "{"birthDate":"2020-11-20 10:43:57","id":100,"age":100,"name":"小米"}";
UserInfo userInfo = mapper.readValue(json, UserInfo.class);
System.out.println(userInfo);
}
//輸出:name序列化 和 反序列化時都會被忽略掉
{"id":1000,"age":100,"birthDate":"2020-11-20 11:25:46"}
============================
UserInfo(id=100, name=null, age=100, birthDate=Fri Nov 20 18:43:57 CST 2020)
@JsonIgnoreProperties註解:物件序列化和反序列化時,忽略物件的多個屬性。
@Data
public class PersonInfo implements Serializable {
private Long Id;
@JsonIgnoreProperties({"name", "age"})
private UserInfo userInfo;
}
#@JsonIgnoreProperties過濾多個屬性:userInfo裡的name和age在序列化和反序列化時會被忽略掉
(6)@JsonAnySetter註解
用於屬性或者方法,設定未反序列化的屬性名和值作為鍵值儲存到map; @JsonAnyGetter用於方法 ,獲取所有未序列化的屬性。 所有被Ignore的屬性 和 物件不存在的屬性在反序列號時,都會調一次@JsonAnySetter的方法。
@Data
public class UserInfo implements Serializable {
private Long id;
@JsonIgnore
private String name;
private Integer age;
private Map<String, Object> map = new HashMap<>();
@JsonAnySetter
public void setOther(String key, Object value) {
System.out.println("key=" + key + " value=" + value);
map.put(key, value);
}
@JsonAnyGetter
public Map<String, Object> getOther() {
return map;
}
}
//測試方法
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
//反序列化時,因為Java物件name屬性有@JsonIgnore會被忽略,Java物件沒有birthDate會被忽略
String json = "{"birthDate":"2020-11-20 10:43:57","id":100,"age":100,"name":"小米"}";
UserInfo userInfo = mapper.readValue(jsonStr, UserInfo.class);
System.out.println(userInfo);
System.out.println(userInfo.any());
}
//輸出:所有被Ignore的屬性 和 物件不存在的屬性在反序列號時,都會調一次@JsonAnySetter的方法。
key=birthDate value=2020-11-20 10:43:57
key=name value=小米
UserInfo(id=100, name=null, age=100, map={name=小米, birthDate=2020-11-20 10:43:57})
{name=小米, birthDate=2020-11-20 10:43:57}
(7)@JsonInclude註解
@JsonInclude(JsonInclude.Include.NON_NULL)註解,將該註解放在屬性上,如果該屬性為null則不參與序列化;如果放在類上邊那對這個類的全部屬性起作用。
#示例
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserInfo implements Serializable {
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT + 8")
private Date birthDate;
}
#測試方法
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
UserInfo info = new UserInfo();
info.setName("訊息");
info.setBirthDate(new Date());
System.out.println(mapper.writeValueAsString(info));
}
#輸出:
{"name":"訊息","birthDate":"2020-11-23 02:10:43"}
#UserInfo類去掉@JsonInclude註解後的輸出:json字串裡會有null屬性存在
{"id":null,"name":"訊息","age":null,"birthDate":"2020-11-23 02:17:54"}
@JsonInclude註解除了NON_NULL的使用,還有其很多型別,詳細參考JsonInclude.Include的列舉類。
#(1)@JsonInclude註解的屬性常用的有一下幾種:
Include.Include.ALWAYS 預設
Include.NON_DEFAULT 屬性為預設值不序列化
Include.NON_EMPTY 屬性為 空("") 或者為 NULL 都不序列化
Include.NON_NULL 屬性為NULL 不序列化
#(2)物件屬性為null不參與序列化,除了使用註解外,也可以直接設定ObjectMapper屬性,如下:
ObjectMapper mapper = new ObjectMapper();
//型別的設定也包含上面四種
mapper.setSerializationInclusion(Include.NON_NULL);
最後,感覺在平時的開發中好多人喜歡用阿里的fastjson,官方評價說是最快的json解析框架,但最近幾年經常出高危漏洞,專案也跟著不斷打復補丁,有時候搞得人心惶惶的,特別被動。於是為了不重複造輪子都將Jackson封裝成統一的工具。參考json工具:JsonUtils工具類
2020年12月06日 晚 於北京記
相關文章
- jackson學習之七:常用Field註解
- jackson學習之八:常用方法註解
- jackson學習之五:JsonInclude註解JSON
- Jackson 解析json資料之忽略解析欄位註解@JsonIgnorePropertiesJSON
- Spring IOC 常用註解與使用Spring
- Spring MVC 常用註解的使用SpringMVC
- Jackson精解第4篇-@JacksonInject與@JsonAlias註解JSON
- 常用註解
- Swagger3註解使用Swagger
- Springboot 常用註解Spring Boot
- Lombok常用註解Lombok
- Spring常用註解Spring
- Solon2 常用註解之 @ProxyComponent 用法說明
- 程式設計師筆記——springboot 之常用註解程式設計師筆記Spring Boot
- spring 框架常用註解Spring框架
- 002 SpringBoot 常用註解Spring Boot
- SpringMvc的常用註解SpringMVC
- MyBatisPlus-常用註解MyBatis
- SwaggerAPI註解詳解,以及註解常用引數配置SwaggerAPI
- 【淺度渣文】Jackson之jackson-annotations
- 【淺度渣文】Jackson之jackson-databind
- Android 註解系列之 EventBus3 原理(四)AndroidS3
- swagger常用註解搬運Swagger
- springboot常用註解記錄Spring Boot
- jackson學習之三:常用API操作API
- Android 註解系列之EventBus3“加速引擎“(五)AndroidS3
- Lombok的常用註解有哪些Lombok
- Spring/SpringBoot常用註解總結Spring Boot
- SpringMvc的常用註解介紹SpringMVC
- Spring學習之05使用註解開發Spring
- @ResponseBody註解和@RequestBody註解使用
- SpringBoot基礎篇Bean之條件注入之註解使用Spring BootBean
- Spring 註解程式設計之模式註解Spring程式設計模式
- spring boot的常用註解有哪些?Spring Boot
- Android MVVM探索(二) - DataBiding常用註解AndroidMVVM
- Swagger2常用註解說明Swagger
- JPA常用註解彙總紀要
- SpringMVC常用註解@Controller,@Service,@repository,@ComponentSpringMVCController