用Jackson自定義JSON反序列化
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
我們將REST API編碼成JSON格式,然後將它解碼到POJO。Jackson的org.codehaus.jackson.map.ObjectMapper“只能”開箱即用,並且在大多數情況下我們並不能做任何其他事情。但有時我們確實需要一個定製的反序列化器以滿足我們的定製需求,所以本教程將指導大家如何建立自定義的反序列化。
比方說,我們有以下實體:
public class User { private Long id; private String name; private String email; public Long getId() { return id; } public User setId(Long id) { this.id = id; return this; } public String getName() { return name; } public User setName(String name) { this.name = name; return this; } public String getEmail() { return email; } public User setEmail(String email) { this.email = email; return this; } @Override public String toString() { final StringBuffer sb = new StringBuffer("User{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", email='").append(email).append('\''); sb.append('}'); return sb.toString(); } }
public class Program { private Long id; private String name; private User createdBy; private String contents; public Program(Long id, String name, String contents, User createdBy) { this.id = id; this.name = name; this.contents = contents; this.createdBy = createdBy; } public Program() {} public Long getId() { return id; } public Program setId(Long id) { this.id = id; return this; } public String getName() { return name; } public Program setName(String name) { this.name = name; return this; } public User getCreatedBy() { return createdBy; } public Program setCreatedBy(User createdBy) { this.createdBy = createdBy; return this; } public String getContents() { return contents; } public Program setContents(String contents) { this.contents = contents; return this; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Program{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", createdBy=").append(createdBy); sb.append(", contents='").append(contents).append('\''); sb.append('}'); return sb.toString(); } }
讓我們序列化/排列第一個物件:
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反序列化到程式物件:
String jsonString = "{\"id\":1,\"name\":\"Program @# 1\",\"createdBy\":{\"id\":1,\"name\":\"Bazlur Rahman\",\"email\":\"example@example.com\"},\"contents\":\"Some contents\"}"; final Program program1 = objectMapper.readValue(jsonString, Program.class); System.out.println(program1);
現在,假設,這不是真正的情況,我們需要有一個來自於API的不同的JSON,而且這個API不匹配我們的程式類:
{ "id": 1, "name": "Program @# 1", "ownerId": 1 "contents": "Some contents" }
從這個JSON字串中,你可以看到,它有owenerId這個不同的欄位。
現在如果你想像先前我們做的那樣序列化此JSON,那麼就會出現異常。
有兩種方法可以避免異常和這樣的序列化:忽略未知欄位,或編寫自定義的反序列化器。
忽略未知欄位
忽略`onwerId`。新增以下注釋到程式類中
@JsonIgnoreProperties(ignoreUnknown = true) public class Program {}
編寫自定義的反序列化器
但是有些時候,你確實需要`owerId`這個欄位。比方說,你需要涉及使用者類的ID。
在這種情況下,你需要編寫自定義的解串器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class ProgramDeserializer extends JsonDeserializer<Program> { @Override public Program deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectCodec oc = jp.getCodec(); JsonNode node = oc.readTree(jp); final Long id = node.get("id").asLong(); final String name = node.get("name").asText(); final String contents = node.get("contents").asText(); final long ownerId = node.get("ownerId").asLong(); User user = new User(); user.setId(ownerId); return new Program(id, name, contents, user); } }
正如你所看到的,首先你得從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.<b>class</b>) public class Program {}
完整的原始碼請見:https://gith
譯文連結:http://www.codeceo.com/article/jackson-json-deserialization.html
英文原文:Custom JSON Deserialization with Jackson
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- @JsonCreator自定義反序列化函式-JSON框架Jackson精解第5篇JSON函式框架
- 屬性序列化自定義與字母表排序-JSON框架Jackson精解第3篇排序JSON框架
- json - 使用jackson進行序列化/反序列化JSON
- jackson進行json序列化和反序列化JSON
- java自定義序列化Java
- Python中巢狀自定義型別的JSON序列化與反序列化Python巢狀型別JSON
- [golang] 結構體json序列化時,如何自定義時間格式Golang結構體JSON
- jackson序列化與反序列化的應用實踐
- .Net Core 自定義序列化格式
- 在Springboot + Mybaitis-plus 專案中利用Jackson實現json對java多型的(反)序列化Spring BootAIJSONJava多型
- Jackson多型序列化多型
- 使用jackson序列化物件物件
- SpringBoot 預設json解析器詳解和欄位序列化自定義Spring BootJSON
- 自定義Object與XML互換(序列化)ObjectXML
- 終極CRUD-3-用Jackson解析jsonJSON
- JSON序列化之旅:深入理解.NET中的JsonResult與自定義ContractResolverJSON
- 原始碼分析springboot自定義jackson序列化,預設null值個性化處理返回值原始碼Spring BootNull
- Json工具類----JacksonJSON
- springbootredis自定義序列化方式(fastJson)Spring BootRedisASTJSON
- JSON資料處理框架Jackson精解第一篇-序列化與反序列化核心用法JSON框架
- Jackson Redisson反序列化問題Redis
- jackson對日期的處理(序列化與反序列化)
- Java序列化與反序列化(原生方式與Jackson方式)Java
- Json序列化在golang中的應用JSONGolang
- JSON 物件序列化、反序列化JSON物件
- Spring Boot之自定義JSON轉換器Spring BootJSON
- WebApi XML,Json格式自定義,IEnumerable<T>,ArrayOfWebAPIXMLJSON
- springboot自定義ObjectMapper序列化、配置序列化對LocalDateTime的支援Spring BootObjectAPPLDA
- netty自定義Decoder用於自定義協議Netty協議
- jackson對Exception型別物件的序列化與反序列化Exception型別物件
- [BUG反饋]自定義模型不顯示資料模型
- Jackson序列化日期型別的屬性型別
- Jackson Gson Json.simple 比較JSON
- Java JSON處理類庫JacksonJavaJSON
- .NET 中Newtonsoft的使用 自定義物件的序列化物件
- Redis序列化儲存Java集合List等自定義型別RedisJava型別
- json-server的實踐與自定義配置化JSONServer
- [BUG反饋]模型屬性自定義函式提交不了模型函式