java enum 转换成json_枚举类型全字段序列化转JSON

背景

最近在构思做一个通用化的字典工具,其中有一个功能就是自动扫描枚举类,将枚举类序列化成一张表,对比更新到数据库中。但是在实际中使用发现,如果不做任何限制,直接用fastjson的JSON.toJSONString(obj) 方法,得到的只是枚举的名字,并没有得到一个全字段的json串。即SUCCESS(0, "成功")得到的将是SUCCESS这个字符串

fastjson版本:1.2.56

解决方案重写覆盖枚举类的toString() 方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17@Getter

@AllArgsConstructor

public enum EnumTest {

SUCCESS(0, "成功"),

FAIL(-1, "失败");

private int code;

private String msg;

@Override

public String toString() {

return "{\n" +

" \"code\": " + getCode() + ",\n" +

" \"msg\": " + getMsg() + "\n" +

"}";

}

}

这样的话,如果直接用EnumTest.SUCCESS.toString()就可以得到想要的结果,但是如果用JSON.toJSONString(EnumTest.SUCCESS)得到的仍然是SUCCESS。这个比较直白简单,但是不支持fastjson的方法,就是手动控制了枚举的toString输出内容,但是也有一个不好的问题就是,新增字段或者修改字段,还得改toString方法,万一忘了改,那可能会发生一些莫名其妙的Bug,而且还不易察觉,所以不推荐。

**NOTE:**注解是用了lombok包里面的一些方法

自定义SerializeConfig

其实仔细看JSON.toJSONString()方法,有一些其他的重载方法提供了一些其他的参数,其中

1

2

3public static String toJSONString(Object object, SerializeConfig config, SerializerFeature... features) {

return toJSONString(object, config, (SerializeFilter) null, features);

}

这个里面有一个自定义序列化的配置参

使用如下:

1

2

3SerializeConfig config = new SerializeConfig();

config.configEnumAsJavaBean(EnumTest.class);

System.out.println(JSON.toJSONString(EnumTest.SUCCESS, config));

我们对比下几个的输出结果:

1

2

3

4

5

6System.out.println("1:" + EnumTest.SUCCESS.toString());

System.out.println("2:" + JSON.toJSONString(EnumTest.SUCCESS));

SerializeConfig config = new SerializeConfig();

config.configEnumAsJavaBean(EnumTest.class);

System.out.println("3:" + JSON.toJSONString(EnumTest.SUCCESS, config));

结果如下:

1

2

3

4

5

61:{

"code": 0,

"msg": 成功

}

2:"SUCCESS"

3:{"code":0,"msg":"成功"}

通过这种方式,可以比较灵活自由的达到我们想要的序列化效果,而没有破坏掉其他的一些引用到枚举类的地方,因为如果直接重载了枚举本身的toString()方法,会产生一些不可预知的错误。

枚举嵌套

对于简单的枚举,这种应该没有啥问题,如果枚举出现了嵌套呢?我们写个例子测试一下,再申明一个EnumTest2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20// 枚举定义

@Getter

@AllArgsConstructor

public enum EnumTest2 {

SUCCESS(0, "成功", EnumTest.SUCCESS),

FAIL(-1, "失败", EnumTest.FAIL);

private int code;

private String msg;

private EnumTest enumTest;

}

// 自定义序列化配置

SerializeConfig config = new SerializeConfig();

config.configEnumAsJavaBean(EnumTest2.class);

System.out.println(JSON.toJSONString(EnumTest2.SUCCESS, config));

// 输出

{"code":0,"enumTest":"SUCCESS","msg":"成功"}

可以看到EnumTest2本身序列化没问题,但是他的enumTest属性没有按照我们想要的方式来,需要改一些:

1

2

3

4// 这个地方改一下

config.configEnumAsJavaBean(EnumTest.class, EnumTest2.class);

// 输出结果

{"code":0,"enumTest":{"code":0,"msg":"成功"},"msg":"成功"}

枚举转字典

其实上面的基本是为了搞清楚枚举的序列化问题,主要目的其实还是为了我们的字典如何同步。因为并不是所有的枚举都需要入库,所以我们需要实现一个注解,当有这个注解的枚举,那么我们会把他同步到字典中。当然还有一个问题就是上面探讨的,如果一个枚举他嵌套了其他的枚举,我们还需要把他所引用的枚举都配置到自定义序列化的配置里,所以实现如下:

同步注解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值