您的位置 首页 java

JSON类库Jackson优雅序列化Java枚举类

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, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                    gen.writeStartObject();
                    gen.writeNumberField("code",value.code());
                    gen.writeStringField("description",value.description());
                    gen.writeEndObject();
​
​
        }
    });
}  

这样就实现了全局配置。

5. 总结

这里我们介绍了如何定制 Jackson 库以达到对枚举进行更加友好的序列化的目的。其实不单单枚举,你也可以实现其它序列化,反序列化,时间输出格式的定制。这些特性留给你自己挖掘。多多关注: 码农小胖哥 获取更多开发技巧。

文章来源:智云一二三科技

文章标题:JSON类库Jackson优雅序列化Java枚举类

文章地址:https://www.zhihuclub.com/185377.shtml

关于作者: 智云科技

热门文章

发表回复

您的电子邮箱地址不会被公开。

网站地图