用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框架
- Python中巢狀自定義型別的JSON序列化與反序列化Python巢狀型別JSON
- 自定義JSON名JSON
- 在Springboot + Mybaitis-plus 專案中利用Jackson實現json對java多型的(反)序列化Spring BootAIJSONJava多型
- java自定義序列化Java
- JSON序列化之旅:深入理解.NET中的JsonResult與自定義ContractResolverJSON
- jackson序列化與反序列化的應用實踐
- Json工具類----JacksonJSON
- SpringBoot 預設json解析器詳解和欄位序列化自定義Spring BootJSON
- 終極CRUD-3-用Jackson解析jsonJSON
- 原始碼分析springboot自定義jackson序列化,預設null值個性化處理返回值原始碼Spring BootNull
- Jackson多型序列化多型
- springbootredis自定義序列化方式(fastJson)Spring BootRedisASTJSON
- system.text.Json 針對繼承多型型別的集合,使用自定義Converter,進行json序列化JSON繼承多型型別
- JSON資料處理框架Jackson精解第一篇-序列化與反序列化核心用法JSON框架
- Jackson Redisson反序列化問題Redis
- springboot自定義ObjectMapper序列化、配置序列化對LocalDateTime的支援Spring BootObjectAPPLDA
- Spring Boot之自定義JSON轉換器Spring BootJSON
- netty自定義Decoder用於自定義協議Netty協議
- Json序列化在golang中的應用JSONGolang
- jackson對日期的處理(序列化與反序列化)
- 使用 Jackson 序列化和反序列化 java.sql.BlobJavaSQL
- T-SQL——自定義函式解析JSON字串SQL函式JSON字串
- JSON解析器之Gson、FastJson、JacksonJSONAST
- JSON-B:簡化 JSON 序列化和反序列化JSON
- jackson對Exception型別物件的序列化與反序列化Exception型別物件
- Kotlin Json 序列化KotlinJSON
- 設定Springboot返回jackson資料序列化Spring Boot
- json-server的實踐與自定義配置化JSONServer
- 省掉bean自定義spring mvc註解注入json值BeanSpringMVCJSON
- 一文搞定Jackson解析JSON資料JSON
- [BUG反饋]自定義模型不顯示資料模型
- 利用Jackson序列化實現資料脫敏
- Newtonsoft.Json序列化JSON字串問題JSON字串
- Jackson 庫中@JsonProperty和@JsonAlias註解實現序列化反序列化JSON
- 7. Jackson用樹模型處理JSON是必備技能,不信你看模型JSON
- 3. 懂了這些,方敢在簡歷上說會用Jackson寫JSONJSON
- Flutter中JSON序列化與反序列化FlutterJSON