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枚举类的更多相关文章

  1. 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)

    本篇文章主要介绍了"两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)",主要涉及到两款JSON类库Jackson与JSON-lib的性能对比(新增第三款 ...

  2. Java枚举类在生产环境中的使用方式

    前言   Java枚举在项目中使用非常普遍,许多人在做项目时,一定会遇到要维护某些业务场景状态的时候,往往会定义一个常量类,然后添加业务场景相关的状态常量.但实际上,生产环境的项目中业务状态的定义大部 ...

  3. JSON类库Jackson与JSON-lib性能对比[转]

    Jackson:http://jackson.codehaus.org/ JSON-lib:http://json-lib.sourceforge.net/ Gson:http://code.goog ...

  4. Java 枚举类

    如果要定义一个枚举类: public enum Size { SAMLL, MEDIUM, LARGE, EXTRA, EXTRA_LARGE}; 实际上,这个声明定义的类型是一个类,它刚好有4个实例 ...

  5. Java基础15:深入剖析Java枚举类

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  6. 夯实Java基础系列14:深入理解Java枚举类

    目录 初探枚举类 枚举类-语法 枚举类的具体使用 使用枚举类的注意事项 枚举类的实现原理 枚举类实战 实战一无参 实战二有一参 实战三有两参 枚举类总结 枚举 API 总结 参考文章 微信公众号 Ja ...

  7. 字节码层面深入分析Java枚举类

    枚举类的使用 定义一个简单的枚举类,其中包含若干枚举常量,示例如下: public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FR ...

  8. java 枚举类 enum 总结

    枚举定义: enum是计算机编程语言中的一种数据类型.枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等.如果把这些量 ...

  9. java 枚举类小结 Enum

    好久没有接触枚举类了,差不多都忘了,今天抽出个时间总结一下吧.说实话,枚举类确实能够给我们带来很大的方便. 说明:枚举类它约定了一个范围,可以理解成只可以生成固定的几个对象让外界去调用,故枚举类中的构 ...

随机推荐

  1. SD.Team字符表情集大全(持续更新中..)

    一.超级可爱的字符表情集 01. <( ̄︶ ̄)> 02. <( ̄︶ ̄)/ 03. b( ̄▽ ̄)d 04. 汗( ̄口 ̄)!! 05. ╮( ̄▽ ̄)╭ 06. ╰( ̄▽ ̄)╭ 07. ╮ ...

  2. jchdl - GSL实例:FullAdder

    https://mp.weixin.qq.com/s/CtT08xZON0YxnheqDM2FAw 全加器是能够计算低位进位的二进制加法电路.与半加器相比,全加器不只考虑本位计算结果是否有进位,也考虑 ...

  3. 基础数论——EXGCD

    1.前言 \(皆さん.こんにちは.\)今天我们来讲 \(EXGCD\) .(扩展欧几里得) 既然是扩展嘛,那肯定有不扩展的,也就是 \(GCD\) . 我们都知道 \(GCD\) 怎么写: ll GC ...

  4. XStream学习手册

    ​​ 一.前言 1.XStream官网 http://x-stream.github.io 2.XStream是什么 XStream是一个简单的基于Java的类库,用来将Java对象序列化成XML(J ...

  5. Java实现 蓝桥杯VIP 算法训练 步与血(递推 || DFS)

    试题 算法训练 步与血 问题描述 有n*n的方格,其中有m个障碍,第i个障碍会消耗你p[i]点血.初始你有C点血,你需要从(1,1)到(n,n),并保证血量大于0,求最小步数. 输入格式 第一行3个整 ...

  6. (Java实现) 工作分配问题

    工作分配问题 时间限制: 1 Sec 内存限制: 128 MB [提交][状态][讨论版] 题目描述 设有n件工作分配给n个人.为第i个人分配工作j所需的费用为c[i][j] .试设计一个算法,计算最 ...

  7. Java实现 蓝桥杯VIP 算法训练 ALGO-85进制转换

    问题描述 编写一个程序,输入一个二进制的字符串(长度不超过32),然后计算出相应的十进制整数,并把它打印出来. 输入格式:输入为一个字符串,每个字符都是'0'或'1',字符串的长度不超过32. 输出格 ...

  8. Java实现 LeetCode 198 打家劫舍

    198. 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报 ...

  9. Java实现One-way traffic(单向交通)

    One-way traffic In a certain town there are n intersections connected by two- and one-way streets. T ...

  10. java实现正六面体染色

    ** 正六面体染色** 正六面体用4种颜色染色. 共有多少种不同的染色样式? 要考虑六面体可以任意旋转.翻转. 参考答案: 240 Burnside引理,正方体涂色问题 (n^6 + 3*n^4 + ...