com.alibaba.fastjson.JSONException: illegal state : 1002

ima
ima
2021-08-07 / 0 评论 / 42 阅读
温馨提示:
本文最后更新于2021-08-07,若内容或图片失效,请留言反馈。

定位报错

JSONReader reader = new JSONReader(new StringReader(str));
....
while (reader.hasNext()) {
     String arrayListItemKey = reader.readString();
    String arrayListItemValue = reader.readObject()== null ? null : reader.readObject().toString();
}

导致报错原因:代码块中使用了两次reader.readObject();

分析下为什么报错?

    public boolean hasNext() {
        if (context == null) {
            throw new JSONException("context is null");
        }

        final int token = parser.lexer.token();
        final int state = context.state;
        switch (state) {
            case StartArray:
            case ArrayValue:
                return token != JSONToken.RBRACKET;
            case StartObject:
            case PropertyValue:
                return token != JSONToken.RBRACE;
            default:
                throw new JSONException("illegal state : " + state);
        }
    }
class JSONStreamContext {

    final static int                  StartObject   = 1001;
    final static int                  PropertyKey   = 1002;
    final static int                  PropertyValue = 1003;
    final static int                  StartArray    = 1004;
    final static int                  ArrayValue    = 1005;

    protected final JSONStreamContext parent;

    protected int                     state;

    public JSONStreamContext(JSONStreamContext parent, int state){
        this.parent = parent;
        this.state = state;
    }
}

大致意思是上一个kv还没有读完,来探究一下reader.readObject()

    public Object readObject() {
        if (context == null) {
            return parser.parse();
        }

        readBefore();
        Object object;
        switch (context.state) {
            case StartObject:
            case PropertyValue:
                object = parser.parseKey();
                break;
            default:
                object = parser.parse();
                break;
        }

        readAfter();
        return object;
    }
    private void readBefore() {
        int state = context.state;
        // before
        switch (state) {
            case PropertyKey:
                parser.accept(JSONToken.COLON);
                break;
            case PropertyValue:
                parser.accept(JSONToken.COMMA, JSONToken.IDENTIFIER);
                break;
            case ArrayValue:
                parser.accept(JSONToken.COMMA);
                break;
            case StartObject:
                break;
            case StartArray:
                break;
            default:
                throw new JSONException("illegal state : " + state);
        }
    }
    private void readAfter() {
        int state = context.state;
        int newStat = -1;
        switch (state) {
            case StartObject:
                newStat = PropertyKey;
                break;
            case PropertyKey:
                newStat = PropertyValue;
                break;
            case PropertyValue:
                newStat = PropertyKey;
                break;
            case ArrayValue:
                break;
            case StartArray:
                newStat = ArrayValue;
                break;
            default:
                throw new JSONException("illegal state : " + state);
        }
        if (newStat != -1) {
            context.state = newStat;
        }
    }

执行两次reader.readObject() 过程中 current.status状态变化是这样的:最开始current.status = 1001 执行第一次reader.readObject() 过程中执行了readAfter(),将状态变成了PropertyKey = 1002,

执行过程大概是这样的 读取kv,读k:执行reader.readString() current.status = 1001-->current.status = 1002
读v:reader.readObject() current.status = 1002 --> current.status = 1003 再次执行reader.readObject() current.status = 1003 --> current.status = 1002 所以到了hasNext() 的时候验证自然不通过。