[alibaba/fastjson]不论是在@JSONField还是@JSONType中自定义Enum反序列化器都是无效的

2025-10-31 107 views
3

温少: 前言:因为项目中的enum类统一需要实现接口EnumAware(提供getCode()、getPrompt())

在enum类型字段上注解@JSONField(name = "l_k_assbalv4", deserializeUsing = EnumAwareSerializer.class)无效。

原因是:在ParserConfig类的getDeserializer(Class<?> clazz, Type type)方法中, 判断clazz是enum类型进入分支处理并最终返回(这里倒是有处理@JSONType)的逻辑,要先于对 @JSONField.deserializeUsing() 的解析(在方法createJavaBeanDeserializer(Class<?> clazz, Type type)中。

            if (derializer != null) {
                return (ObjectDeserializer)derializer;
            } else {
                if (clazz.isEnum()) {
                    deserClass = null;
                    JSONType jsonType = (JSONType)clazz.getAnnotation(JSONType.class);
                    if (jsonType != null) {
                        Class deserClass = jsonType.deserializer();

                        try {
                            derializer = (ObjectDeserializer)deserClass.newInstance();
                            this.deserializers.put(clazz, derializer);
                            return derializer;
                        } catch (Throwable var10) {
                            ;
                        }
                    }

                    derializer = new EnumDeserializer(clazz);
                } else if (clazz.isArray()) {
但是这个EnumDeserializer并不能满足我的需求。为什么不支持我对enum类型的字段使用@JSONField自定义解析器呢?

在对应enum类上注解@JSONType( deserializer = EnumAwareSerializer.class, serializer = EnumAwareSerializer.class)无效。

原因是:在TypeUtils类的方法castToEnum(Object obj, Class clazz, ParserConfig mapping)中,
       ObjectDeserializer derializer = mapping.getDeserializer(clazz);
        if (derializer instanceof EnumDeserializer) {
            EnumDeserializer enumDeserializer = (EnumDeserializer) derializer;
            return (T) enumDeserializer.getEnumByHashCode(TypeUtils.fnv1a_64(name));
        }
        return (T) Enum.valueOf((Class<? extends Enum>) clazz, name);

即便找到了我自定义的解析器,却没有使用它,而是定死了解析方式。

如果对enum类一定使用EnumDeserializer类型的解析器,那能否将这个处理入口拎出来做得通用一些?

回答

4
@JSONType(serializeEnumAsJavaBean = true)

enum上要加这个配置

9

我在1.2.58这个版本上,@JSONType(serializeEnumAsJavaBean = true)添加了这个配置依然不起作用啊

2

1.2.60同样存在@JSONType(deserializer = IEnumDeserializer.class, serializeEnumAsJavaBean = true)并未识别到

是否与我下面使用的方法有关?

com.alibaba.fastjson.JSONArray

    /**
     * @since  1.2.23
     */
    public <T> List<T> toJavaList(Class<T> clazz) {
        List<T> list = new ArrayList<T>(this.size());

        ParserConfig config = ParserConfig.getGlobalInstance();

        for (Object item : this) {
            T classItem = (T) TypeUtils.cast(item, clazz, config);
            list.add(classItem);
        }

        return list;
    }
5

经过尝试,发现只有parse、parseArray、parseObject等解析方法反序列化才生效。

getObject、toJavaObject、toJavaList等转化方法中反序列化不生效

3

如何只在枚举实现的接口上面添加注解,从而实现全局的反序列操作?