JSON类库Jackson优雅序列化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 库以达到对枚举进行更加友好的序列化的目的。其实不单单枚举,你也可以实现其它序列化,反序列化,时间输出格式的定制。这些特性留给你自己挖掘。多多关注: 码农小胖哥 获取更多开发技巧。

关注公众号:Felordcn获取更多资讯

个人博客https://felord.cn

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

原文 

https://juejin.im/post/5ef005b9e51d4573e5741e60

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » JSON类库Jackson优雅序列化Java枚举类

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址