一、背景
项目中定义了很多dto,包含枚举类型,而且这些枚举全都自定义标志码。比如7001 对应 某种操作。返回前台时,需要转化为对应的7001,前台传入后台时也希望7001转化为枚举。
二、研究思路
一开始,研究了fastjson的默认实现。发现只有不自定义类似7001这种默认值的时候,可以自动转化。
阅读了网上大量资料,笔者认为定义一个通用的序列化和发序列化器是最好的实现
三、实现
1.自定义的枚举状态码 全部定义 value字段 ,定一个通用的接口实现 getValue
2.自己的枚举实现这个接口
3.定义序列化器,需要带泛型,这样才通用
public class BaseEnumDeserializer<T extends Enum<T> & EnumWithValue> implements ObjectDeserializer {private final Class<T> enumClass;public BaseEnumDeserializer(Class<T> enumClass) {this.enumClass = enumClass;}@Overridepublic T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {// 解析为intint value = parser.parseObject(int.class);// 遍历所有的枚举实例for (T itemEnum: enumClass.getEnumConstants()) {if (itemEnum.getValue() == value) {// 成功匹配,返回实例return (T) itemEnum;}}// 没有匹配到,可以抛出异常或者返回nullreturn null;}@Overridepublic int getFastMatchToken() {// 处理匹配int值return JSONToken.LITERAL_INT;}
}
public class BaseEnumSerializer<T extends Enum<T> & EnumWithValue> implements ObjectSerializer {@Overridepublic void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {// 强制把值转换为枚举T itemEnum = (T) object;// 序列化为自定义的code属性,输出就行serializer.write(itemEnum.getValue());}
}
4.在定义的dto里面的枚举字段上面加上解析器注解
四、后记
fastjson还是没有微软的newsoftjson好用,需要自己做大量的工作。这个实现算不错的。