fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

[BUG] 反序列化null的list报错

Open wwulfric opened this issue 2 years ago • 6 comments

问题描述

简要描述您碰到的问题。

比如 {"log_entries": null} 应该被正常反序列化,现在会报错 TODO : class com.alibaba.fastjson2.reader.FieldReaderListField

在对应的类型上有注解:@JsonProperty("log_entries") private List<LogEntry> logEntries;

版本:2.0.46

附加信息

如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。

报错来源是FieldReaderList的readFieldValue(JSONReader jsonReader)方法,看起来这个方法里没有判断jsonReader是不是 null

public Object readFieldValue(JSONReader jsonReader) {
        if (jsonReader.jsonb) {
            int entryCnt = jsonReader.startArray();
            if (entryCnt == -1) {
                return null;
            }
            Object[] array = new Object[entryCnt];
            ObjectReader itemObjectReader
                    = getItemObjectReader(
                    jsonReader.getContext());
            for (int i = 0; i < entryCnt; ++i) {
                array[i] = itemObjectReader.readObject(jsonReader, null, null, 0);
            }
            return Arrays.asList(array);
        }

        if (jsonReader.current() == '[') {
            JSONReader.Context ctx = jsonReader.getContext();
            ObjectReader itemObjectReader = getItemObjectReader(ctx);

            Collection list = createList(ctx);
            jsonReader.next();
            while (!jsonReader.nextIfArrayEnd()) {
                list.add(
                        itemObjectReader.readObject(jsonReader, null, null, 0)
                );

                jsonReader.nextIfComma();
            }

            jsonReader.nextIfComma();

            return list;
        }

        if (jsonReader.isString()) {
            String str = jsonReader.readString();
            if (itemType instanceof Class
                    && Number.class.isAssignableFrom((Class<?>) itemType)
            ) {
                Function typeConvert = jsonReader.getContext().getProvider().getTypeConvert(String.class, itemType);
                if (typeConvert != null) {
                    Collection list = createList(jsonReader.getContext());

                    if (str.indexOf(',') != -1) {
                        String[] items = str.split(",");

                        for (String item : items) {
                            Object converted = typeConvert.apply(item);
                            list.add(converted);
                        }
                    }

                    return list;
                }
            }
        }

        throw new JSONException(jsonReader.info("TODO : " + this.getClass()));
    }

是不是应该在最后的throw new JSONException判断是否是null?是null就返回 null?

wwulfric avatar Feb 04 '24 03:02 wwulfric

是这个错误吗?

java.lang.NullPointerException
	at com.alibaba.fastjson2.reader.FieldReader.compareTo(FieldReader.java:331)
	at com.alibaba.fastjson2.reader.ObjectReaderCreator.putIfAbsent(ObjectReaderCreator.java:3160)
	at com.alibaba.fastjson2.reader.ObjectReaderCreator.createFieldReader(ObjectReaderCreator.java:1498)
	at com.alibaba.fastjson2.reader.ObjectReaderCreator.lambda$createFieldReaders$4(ObjectReaderCreator.java:1588)
	at com.alibaba.fastjson2.util.BeanUtils.setters(BeanUtils.java:564)
	at com.alibaba.fastjson2.reader.ObjectReaderCreator.createFieldReaders(ObjectReaderCreator.java:1584)
	at com.alibaba.fastjson2.reader.ObjectReaderCreatorASM.createObjectReader(ObjectReaderCreatorASM.java:259)
	at com.alibaba.fastjson2.reader.ObjectReaderProvider.getObjectReaderInternal(ObjectReaderProvider.java:854)
	at com.alibaba.fastjson2.reader.ObjectReaderProvider.getObjectReader(ObjectReaderProvider.java:746)
	at com.alibaba.fastjson2.JSON.parseObject(JSON.java:720)
	at com.alibaba.fastjson2.issues_2200.Issue2233.test(Issue2233.java:20)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at java.util.ArrayList.forEach(ArrayList.java:1259)

rowstop avatar Feb 04 '24 06:02 rowstop

可以加上泛型 如List<Object>可以解决这个问题

rowstop avatar Feb 04 '24 09:02 rowstop

@rowstop 不是npe,报错是我贴的代码的最后一行:throw new JSONException(jsonReader.info("TODO : " + this.getClass()));

类型没问题,List<MyType> xxx 这样写的

wwulfric avatar Feb 04 '24 09:02 wwulfric

没复现,按理说如果是 null 应该走不到这里,前面就直接返回了 能否给个可复现demo

rowstop avatar Feb 04 '24 10:02 rowstop

哦,没有无参构造方法是不?

rowstop avatar Feb 04 '24 10:02 rowstop

哦,没有无参构造方法是不?

是的,估计用的lombok 的 builder,所以没有默认的无参构造方法

wwulfric avatar Feb 04 '24 10:02 wwulfric

https://github.com/alibaba/fastjson2/releases/tag/2.0.47 问题已修复,请用新版本

wenshao avatar Feb 24 '24 02:02 wenshao