Fastjson枚举序列化和反序列化的推荐实现

一、背景

项目中定义了很多dto,包含枚举类型,而且这些枚举全都自定义标志码。比如7001 对应 某种操作。返回前台时,需要转化为对应的7001,前台传入后台时也希望7001转化为枚举。

二、研究思路

一开始,研究了fastjson的默认实现。发现只有不自定义类似7001这种默认值的时候,可以自动转化。
阅读了网上大量资料,笔者认为定义一个通用的序列化和发序列化器是最好的实现

三、实现

1.自定义的枚举状态码 全部定义 value字段 ,定一个通用的接口实现 getValue
image
2.自己的枚举实现这个接口
image
3.定义序列化器,需要带泛型,这样才通用

public class BaseEnumDeserializer<T extends Enum<T> & EnumWithValue> implements ObjectDeserializer {
    @Override
    public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
        // 解析为int
        int value = parser.parseObject(int.class);
        // 遍历所有的枚举实例
        Class<T> enumClass = (Class<T>) type;
        for (T itemEnum: enumClass.getEnumConstants()) {
            if (itemEnum.getValue() == value) {
                // 成功匹配,返回实例
                return (T) itemEnum;
            }
        }
        // 没有匹配到,可以抛出异常或者返回null
        return null;
    }

    @Override
    public int getFastMatchToken() {
        // 处理匹配int值
        return JSONToken.LITERAL_INT;
    }
}
public class BaseEnumSerializer<T extends Enum<T> & EnumWithValue> implements ObjectSerializer {
    @Override
    public 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里面的枚举字段上面加上解析器注解
image

四、后记

fastjson还是没有微软的newsoftjson好用,需要自己做大量的工作。这个实现算不错的。

posted @ 2024-10-30 10:15  lovefoolself  阅读(480)  评论(0)    收藏  举报