Jackson優雅序列化Java列舉類過程解析
阿新 • • 發佈:2020-09-04
1. 前言
在Java開發中我們為了避免過多的魔法值,使用列舉類來封裝一些靜態的狀態程式碼。但是在將這些列舉的意思正確而全面的返回給前端卻並不是那麼順利,我們通常會使用Jackson類庫序列化物件為JSON,今天就來講一個關於使用Jackson序列化列舉的通用性技巧。
2. 通用列舉正規化
為了便於統一處理和規範統一的風格,建議指定一個統一的抽象介面,例如:
/** * The interface Enumerator. */ public interface Enumerator { /** * Code integer. * * @return the integer */ Integer code(); /** * Description string. * * @return the string */ String description(); }
我們來寫一個實現來標識性別:
public enum GenderEnum implements Enumerator { UNKNOWN(0,"未知"),MALE(1,"男"),FEMALE(2,"女"); private final Integer code; private final String description; GenderEnum(Integer code,String description) { this.code = code; this.description = description; } @Override public Integer code() { return code; } @Override public String description() { return description; } }
3. 序列化列舉
如果我們直接使用Jackson對列舉進行序列化,將只能簡單的輸出列舉的String名稱:
@Resource private ObjectMapper objectMapper; @Test void enumTest() { try { String s = objectMapper.writeValueAsString(GenderEnum.MALE); // 輸出字串 MALE System.out.println(s); } catch (JsonProcessingException e) { e.printStackTrace(); } }
我們期望將GenderEnum.MALE 序列化為 {"code":1,"description":"男"} 。我們可以向ObjectMapper定製化一個Module來實現這種個性化需求:
// 宣告一個簡單Module 物件 SimpleModule module = new SimpleModule(); // 給Module 新增一個序列化器 module.addSerializer(Enumerator.class,new JsonSerializer<Enumerator>() { @Override public void serialize(Enumerator value,JsonGenerator gen,SerializerProvider serializers) throws IOException { // 開始寫入物件 gen.writeStartObject(); // 分別指定 k v code description gen.writeNumberField("code",value.code()); gen.writeStringField("description",value.description()); // 顯式結束操作 gen.writeEndObject(); } }); // 註冊 Module objectMapper.registerModule(module);
然後再次執行就會獲取我們期望的結果。然而這並不算合理。
4. Spring Boot 中自動全域性配置
在Spring Boot應用中我們希望能全域性配置。Spring Boot的自動配置為我們提供了一個個性化定製ObjectMapper的可能性,你只需要宣告一個Jackson2ObjectMapperBuilderCustomizer並注入Spring IoC:
@Bean public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){ return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class,new JsonSerializer<Enumerator>() { @Override public void serialize(Enumerator value,SerializerProvider serializers) throws IOException { gen.writeStartObject(); gen.writeNumberField("code",value.description()); gen.writeEndObject(); } }); }
這樣就實現了全域性配置。
5. 總結
這裡我們介紹瞭如何定製Jackson庫以達到對列舉進行更加友好的序列化的目的。其實不單單列舉,你也可以實現其它序列化,反序列化,時間輸出格式的定製。這些特性留給你自己挖掘。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。