推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

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

   2023-07-03 网络整理佚名1710
核心提示:在Java开发中我们为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码。但是在将这些枚举的意思正确而全面的返回给前端却并不是那么顺利,我们通常会使用类库序列化对象为JSON,今天就来讲一个关于使用序列化枚举的通用性技巧。序列化枚举这里我们介绍了如何定制库以达到对枚举进行更加友好的序列化的目的。其实不单单枚举,你也可以实现其它序列化,反序列化,时间输出格式的定制。

1 简介

在Java开发中,为了避免魔法值过多,我们使用枚举类来封装一些静态状态码。 然而,要将这些枚举的含义正确、全面地返回给前端,并不是那么顺利。 我们通常使用类库将对象序列化为 JSON。 今天我将讨论有关使用序列化枚举的通用技术。

2. 通用枚举范式

为了便于统一处理,规范统一风格,建议指定统一的抽象接口,例如:


public interface Enumerator {
    
    Integer code();
​
    
    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. 序列化枚举

如果我们直接序列化枚举,我们将简单地输出枚举的名称:

    @Resource
    private ObjectMapper objectMapper;
​
    @Test
    void enumTest() {
        try {
            String s = objectMapper.writevalueAsString(GenderEnum.MALE);
            // 输出字符串 MALE
            System.out.println(s);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

我们期望 .MALE 被序列化为 {"code":1,"":"Male"}。 我们可以定制一个来实现这一个性化需求:

         // 声明一个简单Module 对象
         SimpleModule module = new SimpleModule();
           // 给Module 添加一个序列化器
            module.addSerializer(Enumerator.class, new JsonSerializer() {
                @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. Boot中自动全局配置

在Boot应用中,我们希望进行全局配置。 Boot的自动配置为我们提供了个性化定制的可能,只需要声明一个并注入IoC即可:

@Bean
public Jackson2ObjectMapperBuilderCustomizer enumCustomizer(){
    return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.serializerByType(Enumerator.class, new JsonSerializer() {
        @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. 总结

这里介绍如何自定义该库来实现更友好的枚举序列化。 其实不只是枚举,你还可以实现其他的序列化、反序列化、以及时间输出格式的自定义。 这些功能留给您去发现。 多多关注:码农小胖,了解更多开发技巧。

 
标签: 序列化
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON