枚举类型全字段序列化转JSON
背景
最近在构思做一个通用化的字典工具,其中有一个功能就是自动扫描枚举类,将枚举类序列化成一张表,对比更新到数据库中。但是在实际中使用发现,如果不做任何限制,直接用fastjson
的JSON.toJSONString(obj)
方法,得到的只是枚举的名字,并没有得到一个全字段的json串。即SUCCESS(0, "成功")
得到的将是SUCCESS
这个字符串
fastjson版本:1.2.56
解决方案
- 重写覆盖枚举类的toString() 方法
1 | @Getter |
这样的话,如果直接用EnumTest.SUCCESS.toString()
就可以得到想要的结果,但是如果用JSON.toJSONString(EnumTest.SUCCESS)
得到的仍然是SUCCESS
。这个比较直白简单,但是不支持fastjson
的方法,就是手动控制了枚举的toString
输出内容,但是也有一个不好的问题就是,新增字段或者修改字段,还得改toString
方法,万一忘了改,那可能会发生一些莫名其妙的Bug,而且还不易察觉,所以不推荐。
**NOTE:**注解是用了lombok
包里面的一些方法
- 自定义SerializeConfig
其实仔细看JSON.toJSONString()
方法,有一些其他的重载方法提供了一些其他的参数,其中
1 | public static String toJSONString(Object object, SerializeConfig config, SerializerFeature... features) { |
这个里面有一个自定义序列化的配置参
使用如下:
1 | SerializeConfig config = new SerializeConfig(); |
我们对比下几个的输出结果:
1 | System.out.println("1:" + EnumTest.SUCCESS.toString()); |
结果如下:
1 | 1:{ |
通过这种方式,可以比较灵活自由的达到我们想要的序列化效果,而没有破坏掉其他的一些引用到枚举类的地方,因为如果直接重载了枚举本身的toString()
方法,会产生一些不可预知的错误。
枚举嵌套
对于简单的枚举,这种应该没有啥问题,如果枚举出现了嵌套呢?我们写个例子测试一下,再申明一个EnumTest2
1 | // 枚举定义 |
可以看到EnumTest2
本身序列化没问题,但是他的enumTest
属性没有按照我们想要的方式来,需要改一些:
1 | // 这个地方改一下 |
枚举转字典
其实上面的基本是为了搞清楚枚举的序列化问题,主要目的其实还是为了我们的字典如何同步。因为并不是所有的枚举都需要入库,所以我们需要实现一个注解,当有这个注解的枚举,那么我们会把他同步到字典中。当然还有一个问题就是上面探讨的,如果一个枚举他嵌套了其他的枚举,我们还需要把他所引用的枚举都配置到自定义序列化的配置里,所以实现如下: