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

kcrjzv8t  于 2021-11-27  发布在  Java
关注(0)|答案(4)|浏览(623)

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

  1. 在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自定义解析器呢?
  1. 在对应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类型的解析器,那能否将这个处理入口拎出来做得通用一些?
puruo6ea

puruo6ea1#

@JSONType(serializeEnumAsJavaBean = true)

enum上要加这个配置

ar7v8xwq

ar7v8xwq2#

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

62lalag4

62lalag43#

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;
    }
djmepvbi

djmepvbi4#

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

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

相关问题