- json object操作
- 序列化操作
- 反序列化
- 日期類型反序列化
- 自定義反序列化
- 枚舉類型反序列化
背景
最近由于阿裡的fastjson頻繁爆出安全漏洞,為了避免後續更新上線的煩惱,決定棄用fastjson,使用Jackson,把現有項目中的fastjson都換成了Jackson,由于很多寫法上有些不同,是以在這裡把這些改過的東西做一下筆記。
常用操作
首先引入相關的pom
<properties>
<jackson.version>2.11.0</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
複制
json object操作
當我們需要一個json對象和json數組的時候,我們可以使用下面的方法來構造ObjectNode和ArrayNode,類似fastjson中的JSONObject和JSONArray。
@Test
public void testJsonObject(){
ObjectMapper mapper = new ObjectMapper();
ObjectNode json = mapper.createObjectNode();
json.put("name", "Tom");
json.put("age", 1);
System.out.println(json);
ArrayNode jsonNodes = mapper.createArrayNode();
jsonNodes.add(json);
System.out.println(jsonNodes);
}
複制
序列化操作
序列化操作就是将Java對象轉化成json,簡單的文法如下:
@Test
public void testSerialize() throws JsonProcessingException{
User user = new User();
user.setAge(1);
user.setName("zhangsan");
user.setGender(GENDER.MALE);
user.setBirthday(new Date());
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(user);
System.out.println(s);
}
複制
普通的String和int類型沒有什麼疑問,我們這裡涉及了兩個特殊類型,一個是Date,還有一個是枚舉。
日期類型我們是通過注解@JsonFormat對日期類型做了格式化,可以控制輸出的日期格式。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;
複制
枚舉類型,我們通過注解@JsonValue來控制輸出哪個字段。
@JsonValue
public String getName(){
return name;
}
複制

反序列化
反序列化就是将json轉化成Java對象,文法如下:
@Test
public void testDeSerialize() throws JsonProcessingException{
String json = "{\"name\":\"zhangsan\",\"age\":10}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user);
}
複制
日期類型反序列化
對于Date類型,目前支援以下的格式:
- long類型的時間戳
- 通過@JsonFormat 注解指定類型格式:yyyy-MM-dd HH:mm:ss
@Test
public void testDeSerializeDate() throws JsonProcessingException{
String json = "{\"name\":\"zhangsan\",\"age\":10,\"birthday\":1592800446397}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user);
String json1 = "{\"name\":\"zhangsan\",\"age\":10,\"birthday\":\"2020-01-01 12:13:14\"}";
User user1 = mapper.readValue(json1, User.class);
System.out.println(user1);
}
複制
自定義反序列化
有時候系統提供的反序列化方式不能滿足我們的需求,我們可以自定義一些方法來滿足我們個性化的需求,我們以一個日期為例,講講如何自定義反序列化。
首先我們在對應的字段上通過注解@JsonDeserialize來指定反序列化的類
@JsonDeserialize(using = CustomDeserializerDate.class)
private Date birthday_custom;
複制
自定義的序列化類繼承抽象類StdDeserializer,此外我們還要添加一個無參構造方法,否則會報錯。
在deserialize方法裡我們實作反序列化的邏輯.
public static class CustomDeserializerDate extends StdDeserializer<Date>{
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
protected CustomDeserializerDate(Class<?> vc){
super(vc);
}
//需要一個無參構造方法,否則會報錯
public CustomDeserializerDate(){
this(null);
}
@Override
public Date deserialize(
JsonParser p,
DeserializationContext ctxt) throws IOException{
String date = p.getText();
try {
return sdf.parse(date);
} catch (ParseException e){
e.printStackTrace();
}
return null;
}
}
複制
枚舉類型反序列化
最後我們講一下枚舉類型的反序列化
如下代碼所示,我們通過注解@JsonCreator來處理枚舉反序列化,該方法接收一個int類型的參數,也就是枚舉的value值,傳回枚舉類型GENDER。如果沒找到,則傳回null.
public static enum GENDER{
MALE("男", 1), FEMALE("女", 0);
private String name;
private int value;
@JsonCreator
public static GENDER getGenderById(int value){
for (GENDER c: GENDER.values()){
if (c.getValue() == value){
return c;
}
}
return null;
}
..........
}
複制
完整代碼請參考:https://github.com/zhangjun0x01/bigdata-examples/blob/master/java/src/main/java/json/JacksonTest.java