Jackson优雅序列化Java枚举类过程解析

所属分类: 软件编程 / java 阅读数: 85
收藏 0 赞 0 分享

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库以达到对枚举进行更加友好的序列化的目的。其实不单单枚举,你也可以实现其它序列化,反序列化,时间输出格式的定制。这些特性留给你自己挖掘。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

利用MultipartFile实现文件上传功能

这篇文章主要为大家详细介绍了利用MultipartFile实现文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java编程实现NBA赛事接口调用实例代码

这篇文章主要介绍了Java编程实现NBA赛事接口调用实例代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java编程之双重循环打印图形

这篇文章主要介绍了Java编程之双重循环打印图形,属于Java编程基础练习部分,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

java基础学习JVM中GC的算法

这篇文章主要介绍了java基础学习JVM中GC的算法,通过图文加深对GC算法思路的理解。
收藏 0 赞 0 分享

Java编程Post数据请求和接收代码详解

这篇文章主要介绍了Java编程Post数据请求和接收代码详解,涉及enctype的三种编码,post与get等相关内容,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Retrofit+Rxjava实现文件上传和下载功能

这篇文章主要介绍了Retrofit+Rxjava实现文件上传和下载功能,文中提到了单文件上传和多文件上传及相关参数的请求,需要的朋友参考下吧
收藏 0 赞 0 分享

Retrofit+Rxjava下载文件进度的实现

这篇文章主要介绍了Retrofit+Rxjava下载文件进度的实现,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

java检查服务器的连通两种方法代码分享

这篇文章主要介绍了java检查服务器的连通两种方法代码分享,涉及ping的介绍以及检查服务器连通的两种方法代码示例,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Java/Android 获取网络重定向文件的真实URL的示例代码

本篇文章主要介绍了Java/Android 获取网络重定向文件的真实URL的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

java并发编程之同步器代码示例

这篇文章主要介绍了java并发编程之同步器代码示例,分享了相关代码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享
查看更多