Jackson优雅序列化Java枚举类过程解析
1.前言
在Java开发中我们为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码。但是在将这些枚举的意思正确而全面的返回给前端却并不是那么顺利,我们通常会使用Jackson类库序列化对象为JSON,今天就来讲一个关于使用Jackson序列化枚举的通用性技巧。
2.通用枚举范式
为了便于统一处理和规范统一的风格,建议指定一个统一的抽象接口,例如:
/** *TheinterfaceEnumerator. */ publicinterfaceEnumerator{ /** *Codeinteger. * *@returntheinteger */ Integercode(); /** *Descriptionstring. * *@returnthestring */ Stringdescription(); }
我们来写一个实现来标识性别:
publicenumGenderEnumimplementsEnumerator{ UNKNOWN(0,"未知"), MALE(1,"男"), FEMALE(2,"女"); privatefinalIntegercode; privatefinalStringdescription; GenderEnum(Integercode,Stringdescription){ this.code=code; this.description=description; } @Override publicIntegercode(){ returncode; } @Override publicStringdescription(){ returndescription; } }
3.序列化枚举
如果我们直接使用Jackson对枚举进行序列化,将只能简单的输出枚举的String名称:
@Resource privateObjectMapperobjectMapper; @Test voidenumTest(){ try{ Strings=objectMapper.writeValueAsString(GenderEnum.MALE); //输出字符串MALE System.out.println(s); }catch(JsonProcessingExceptione){ e.printStackTrace(); } }
我们期望将GenderEnum.MALE序列化为{"code":1,"description":"男"}。我们可以向ObjectMapper定制化一个Module来实现这种个性化需求:
//声明一个简单Module对象 SimpleModulemodule=newSimpleModule(); //给Module添加一个序列化器 module.addSerializer(Enumerator.class,newJsonSerializer(){ @Override publicvoidserialize(Enumeratorvalue,JsonGeneratorgen,SerializerProviderserializers)throwsIOException{ //开始写入对象 gen.writeStartObject(); //分别指定kvcodedescription gen.writeNumberField("code",value.code()); gen.writeStringField("description",value.description()); //显式结束操作 gen.writeEndObject(); } }); //注册Module objectMapper.registerModule(module);
然后再次执行就会获取我们期望的结果。然而这并不算合理。
4.SpringBoot中自动全局配置
在SpringBoot应用中我们希望能全局配置。SpringBoot的自动配置为我们提供了一个个性化定制ObjectMapper的可能性,你只需要声明一个Jackson2ObjectMapperBuilderCustomizer并注入SpringIoC:
@Bean publicJackson2ObjectMapperBuilderCustomizerenumCustomizer(){ returnjacksonObjectMapperBuilder->jacksonObjectMapperBuilder.serializerByType(Enumerator.class,newJsonSerializer(){ @Override publicvoidserialize(Enumeratorvalue,JsonGeneratorgen,SerializerProviderserializers)throwsIOException{ gen.writeStartObject(); gen.writeNumberField("code",value.code()); gen.writeStringField("description",value.description()); gen.writeEndObject(); } }); }
这样就实现了全局配置。
5.总结
这里我们介绍了如何定制Jackson库以达到对枚举进行更加友好的序列化的目的。其实不单单枚举,你也可以实现其它序列化,反序列化,时间输出格式的定制。这些特性留给你自己挖掘。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。