使用 Jackson 自定義 JSON 反序列化
我們將 rest API 作為 JSON 格式使用,然後將其解組為 POJO。傑克遜的 org.codehaus.jackson.map.ObjectMapper只是工作開箱即用,在大多數情況下我們真的不做任何事情。但有時我們需要自定義反序列化器來滿足我們的自定義需求,本教程將指導你完成建立自定義反序列化程式的過程。
假設我們有以下實體。
public class User {
private Long id;
private String name;
private String email;
//getter setter are omitted for clarity
}
和
public class Program {
private Long id;
private String name;
private User createdBy;
private String contents;
//getter setter are omitted for clarity
}
讓我們首先序列化/編組一個物件。
User user = new User();
user.setId(1L);
user.setEmail("example@example.com");
user.setName("Bazlur Rahman");
Program program = new Program();
program.setId(1L);
program.setName("Program @# 1");
program.setCreatedBy(user);
program.setContents("Some contents");
ObjectMapper objectMapper = new ObjectMapper();
final String json = objectMapper.writeValueAsString(program); 的 System.out.println(JSON);
以上程式碼將生成以下 JSON-
{
"id": 1,
"name": "Program @# 1",
"createdBy": {
"id": 1,
"name": "Bazlur Rahman",
"email": "example@example.com"
},
"contents": "Some contents"
}
現在可以很容易地做到相反。如果我們有這個 JSON,我們可以使用 ObjectMapper 解組一個程式物件,如下所示 -
現在讓我們說,這不是真實的情況,我們將從 API 中獲得與我們的 Program
類不匹配的不同 JSON。
{
"id": 1,
"name": "Program @# 1",
"ownerId": 1
"contents": "Some contents"
}
檢視 JSON 字串,你可以看到,它有一個與 owenerId 不同的欄位。
現在,如果你想像我們之前所做的那樣序列化這個 JSON,那麼你將有例外。
有兩種方法可以避免異常並將其序列化 -
忽略未知欄位
忽略 onwerId
。在 Program 類中新增以下注釋
@JsonIgnoreProperties(ignoreUnknown = true)
public class Program {}
編寫自定義反序列化程式
但是有些情況下你真的需要這個 owerId
欄位。假設你想將它作為 User
類的 id。
在這種情況下,你需要編寫自定義反序列化器 -
如你所見,首先你必須從 JonsParser
訪問 JsonNode
。然後,你可以使用 get()
方法輕鬆地從 JsonNode
中提取資訊。你必須確保欄位名稱。它應該是確切的名稱,拼寫錯誤會導致異常。
最後,你必須將你的 ProgramDeserializer 註冊到 ObjectMapper
。
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Program.class, new ProgramDeserializer());
mapper.registerModule(module);
String newJsonString = "{\"id\":1,\"name\":\"Program @# 1\",\"ownerId\":1,\"contents\":\"Some contents\"}";
final Program program2 = mapper.readValue(newJsonString, Program.class);
或者,你可以使用註釋直接註冊解串器 -
@JsonDeserialize(using = ProgramDeserializer.class)
public class Program {
}