json是我們現代網際網路程式最常用的互動格式,是否你在工作中會遇到前端說欄位不一致需要改的需求,是否遇到過資料庫欄位名與javaBean的規範不同,是否遇到過json與javaBean相互轉換時因為需求寫的土匪程式碼,這些都可以用Jackson完成,我們經常和json打交道,而Jackson就是幫助我們更好的處理json的框架,SpringBoot預設自帶,還有一款Fastjson,阿里開源的,國內這兩種用的比較多,我選擇了Jackson,老牌穩定。
先來了解兩個概念:
Jackson庫有兩個核心類:ObjectMapper和JsonNode。
ObjectMapper類是Jackson庫中最重要的類,它提供了序列化和反序列化Java物件與JSON之間的轉換。ObjectMapper類的範例是執行緒安全的,可以在多執行緒環境中共用。
JsonNode類是一個抽象類,它代表了一個JSON節點。JsonNode類有多個子類,例如ObjectNode、ArrayNode、ValueNode等,分別對應JSON中的物件、陣列和值。JsonNode類提供了方便的方法來讀取JSON節點的值。
註解是我們最常用的方式,直接選擇常用的開搞,全註解 http://https://www.baeldung.com/jackson-annotations
@JsonProperty 序列化與反序列化別名,作用於屬性上
JsonFormat.Shape.STRING
:將屬性序列化為字串。JsonFormat.Shape.NUMBER
:將屬性序列化為數位。JsonFormat.Shape.ARRAY
:將屬性序列化為陣列。JsonFormat.Shape.OBJECT
:將屬性序列化為物件。如果將 lenient 屬性設定為 true,則在反序列化過程中可以允許一些非嚴格匹配的輸入。例如,如果輸入的日期字串為 "2021-01",它並不符合完整的 "yyyy-MM-dd" 格式,但由於 lenient 設定為 true,Jackson 可以進行寬鬆解析,將其解釋為 2021 年 1 月的某個日期(如 2021 年 1 月 1 日)。
@JsonUnwrapped 序列與反序列化時物件屬性是否需要展開在父物件上,Map不適用,Map用@JsonAnyGetter
例如:
public class User {
private String name;
@JsonUnwrapped
private Address address;
}
public class Address {
private String street;
private String city;
}
結果
{
"name": "John",
"street": "123 Main St",
"city": "New York"
}
@JsonPropertyOrder 序列化時排列排列順序
@JsonIgnore 序列化時忽略的屬性,作用於屬性上
@JsonIgnoreProperties 序列化忽略的屬性集合,作用於類上
@JsonIgnoreType 忽略註釋型別的所有屬性,作用於類上
@JsonInclude 序列化時,值為規則這個屬性隱藏,作用於類和屬性上
JsonInclude.Include.ALWAYS
:始終包含屬性,即使屬性值為 null。JsonInclude.Include.NON_NULL
:僅在屬性值不為 null 時才包含屬性。JsonInclude.Include.NON_DEFAULT
:僅在屬性值與預設值不相等時才包含屬性。JsonInclude.Include.NON_EMPTY
:僅在屬性值不為 null 且不為空(例如空字串或空集合)時才包含屬性。@JsonAnyGetter 註釋允許靈活地將Map屬性用作標準屬性平鋪在父物件上,適用序列化,作用於get方法上,返序列化用@JsonAnySetter
例如:
@Data
public class OrderDetails {
Map<String, String> tempMap = new HashMap<String, String>(){{
put("temp","temp");
put("temp1","temp1");
}};
@JsonAnyGetter
public Map<String, String> getTempMap() {
return tempMap;
}
}
結果
{
"temp": "temp",
"temp1": "temp1"
}
@JsonGetter 序列化時別名,作用於get方法上
@JsonView 序列與反序列化 分組選擇需要顯示的屬性
例子:
@Data
public class OrderDetails {
public interface UserSimpleView {};
public interface UserDetailView {};
@JsonView({UserSimpleView.class,UserDetailView.class})
String name = "yues";
@JsonView(UserDetailView.class)
String password = "123";
}
結果:
@JsonView(OrderDetails.UserSimpleView.class)
@RequestMapping("/add")
public Object add(@RequestBody OrderDetails orderDetails) {
// {
// "name": "yues"
// }
return orderDetails;
}
@JsonView(OrderDetails.UserDetailView.class)
@RequestMapping("/add")
public Object add(@RequestBody OrderDetails orderDetails) {
// {
// "name": "yues",
// "password": "123"
// }
return orderDetails;
}
@JsonRootName 包一層
例子:
@Data
@JsonRootName("user")
public class OrderDetails {
String name = "yues";
}
{
"user": {
"name": "yues"
},
}
@JsonSerialize 自定義序列化器
值為null不會執行
@JsonGetter 反序列化時別名,作用於set方法上
@JsonAlias 反序列化時別名,可以應用於類的屬性上且可以指定多個
@JsonDeserialize 自定義反序列化器
例子
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id", "dateCreated" })
@JsonDeserialize //自定義反序列化
@@JsonSerialize //自定義序列化
public @interface CustomAnnotation {}
以上的註解都可以使用ObjectMapper物件來設定,先有ObjectMapper才有的這些註解,上面的註解都是使用ObjectMapper來完成的,在SpringBoot中我們還可以用ObjectMapper Bean來達到全域性設定,當然也可以用組態檔。在日常的開發工作中,我們經常全域性制定日期格式、駝峰_轉換等等。
這裡就不多做使用ObjectMapper來詳細說,貼一些常用的方法吧
ObjectMapper mapper = new ObjectMapper()
mapper.enable(序列化設定);
mapper.configure(反序列化設定);
// 將字串、byte[]轉換為物件 序列化
mapper.readValue(jsonString, User.class);
// 此方法更靈活,可以只將使用者感興趣的Json串資訊值提取出來 序列化
mapper.readTree(test);
// 將物件轉換為json字串 反序列化
mapper.writeValueAsString(user);
// 將物件轉換為byte 反序列化
mapper.writeValueAsBytes(user)