JSON類庫Jackson優雅序列化Java枚舉類

1. 前言

Java開發中咱們爲了不過多的魔法值,使用枚舉類來封裝一些靜態的狀態代碼。可是在將這些枚舉的意思正確而全面的返回給前端卻並非那麼順利,咱們一般會使用Jackson類庫序列化對象爲JSON,今天就來說一個關於使用Jackson序列化枚舉的通用性技巧。前端

2. 通用枚舉範式

爲了便於統一處理和規範統一的風格,建議指定一個統一的抽象接口,例如:java

/**
 * The interface Enumerator.
 */
public interface Enumerator {
    /**
     * Code integer.
     *
     * @return the integer
     */
    Integer code();

    /**
     * Description string.
     *
     * @return the string
     */
    String description();
}

咱們來寫一個實現來標識性別:app

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名稱:ide

@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來實現這種個性化需求:ui

// 聲明一個簡單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);

而後再次執行就會獲取咱們指望的結果。然而這並不算合理。this

4. Spring Boot 中自動全局配置

Spring Boot應用中咱們但願能全局配置。Spring Boot的自動配置爲咱們提供了一個個性化定製ObjectMapper的可能性,你只須要聲明一個Jackson2ObjectMapperBuilderCustomizer並注入Spring IoC:spa

@Bean
public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){
    return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class, new JsonSerializer<Enumerator>() {
        @Override
        public void serialize(Enumerator value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeStartObject();
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    gen.writeEndObject();


        }
    });
}

這樣就實現了全局配置。code

5. 總結

這裏咱們介紹瞭如何定製Jackson庫以達到對枚舉進行更加友好的序列化的目的。其實不僅僅枚舉,你也能夠實現其它序列化,反序列化,時間輸出格式的定製。這些特性留給你本身挖掘。多多關注:碼農小胖哥 獲取更多開發技巧。對象

關注公衆號:Felordcn 獲取更多資訊blog

我的博客:https://felord.cn

相關文章
相關標籤/搜索