SpringBoot中預設json轉換工具Jackson
Spring Boot 內建了jackson來完成JSON的序列化和反序列化操作。Jackson使用ObjectMapper類將POJO物件序列化成JSON字串,也能將JSON字串反序列化成POJO物件。
JackSon支援三種層次的序列化和反序列化方式:
- 採用JsonParser來解析JSON,解析結果是一串Tokens,採用JsonGenerator來生成JSON,這是最底層的方式。
- 採用樹遍歷方式,JSON被讀入到JsonNode物件中,可以像操作XML DOM那樣讀取JSON。
- 採用DataBind方式,將POJO序列化成JSON,或者反序列化到POJO,這是最直接和最簡單的一種方式,不過有時候需要輔助Jackson的註解或者上述序列化實現類來個性化序列化和反序列化操作。
1.物件繫結
應用程式更常見的是使用Java物件來與JSON資料互相繫結,僅僅呼叫ObjectMapper的readValue來實現,我們現在舉個例子,可以建立一個POJO物件來與JSON相對應,POJO類如下:
public class User { Long id; String name; public Long getId() {return id;} public void setId(Long id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} }
(1)使用readValue方法來反序列化上面的JSON字串,即json轉換為物件:
@Autowired private ObjectMapper mapper; @GetMapping("/dataBind.json") public @ResponseBody String dataBind() throws IOException{ String json = "{"name":"lijz","id":10}"; User user = mapper.readValue(json, User.class); return "name:"+user.getName()+",id:"+user.getId(); }
(2)將POJO序列化成JSON,使用mapper的writeValueAsString方法:
@Autowired
private ObjectMapper mapper;
@GetMapping("/serialization.json")
public @ResponseBody String dataBind() throws IOException{
User user = new User();
user.setName("scg");
user.setId((long) 18);
String jsonStr = mapper.writeValueAsString(user);
return jsonStr;
}
(3)json轉集合
json轉集合比較麻煩,因為你無法同時把集合的class和元素的class同時傳遞到一個引數。因此Jackson做了一個型別工廠,用來解決這個問題:
// json處理工具
private ObjectMapper mapper = new ObjectMapper();
@Test
public void testJson() throws IOException {
User user = new User();
user.setId(8L);
user.setAge(21);
user.setName("柳巖");
user.setUserName("liuyan");
// 序列化,得到物件集合的json字串
String json = mapper.writeValueAsString(Arrays.asList(user, user));
// 反序列化,接收兩個引數:json資料,反序列化的目標類位元組碼
List<User> users = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, User.class));
for (User u : users) {
System.out.println("u = " + u);
}
}
(4)json轉任意複雜型別
當物件泛型關係複雜時,型別工廠也不好使了。這個時候Jackson提供了TypeReference來接收型別泛型,然後底層通過反射來獲取泛型上的具體型別。實現資料轉換。
// json處理工具
private ObjectMapper mapper = new ObjectMapper();
@Test
public void testJson() throws IOException {
User user = new User();
user.setId(8L);
user.setAge(21);
user.setName("柳巖");
user.setUserName("liuyan");
// 序列化,得到物件集合的json字串
String json = mapper.writeValueAsString(Arrays.asList(user, user));
// 反序列化,接收兩個引數:json資料,反序列化的目標類位元組碼
List<User> users = mapper.readValue(json, new TypeReference<List<User>>(){});
for (User u : users) {
System.out.println("u = " + u);
}
}
2.Jackson 註解
Jackson包含了很多註解,用來個性化序列化和反序列化操作,主要有如下註解。
(1)@JsonProperty,作用在屬性上,用來為JSON Key指定一個別名。
@JsonProperty("userName")
private String name;
(2)@JsonIgnore,作用在屬性上,用來忽略此屬性。
@JsonIgnore
private String age;
(3)@JsonIgnoreProperties,忽略一組屬性,作用於類上
@JsonIgnoreProperties({"id","photo"})
public class User {}
(4)@JsonFormat,用於日期格式化。
@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")
private Date d;
(5)@JsonView,作用在類或者屬性上,用來定義一個序列化組。Spring MVC的Controller方法可以使用同樣的@JsonView來序列化屬於這一組的配置。比如對於User物件,某些情況下只返回id屬性就行,而某些情況下需要返回id和名稱。程式碼如下:
public class User {
public interface IdView{};
public interface IdNameView extends IdView{};
@JsonView(IdView.class)
private Integer id;
@JsonView(IdNameView.class)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* controller
*/
@JsonView(User.IdView.class)
@RequestMapping("/id.json")
public @ResponseBody User queryIds(){
User user = new User();
user.setId(1);
user.setName("scg");
return user;
}
(6)@JsonSerialize,指定一個實現類來自定義序列化。類必須實現JsonSerializer介面。