alibaba / fastjson2

🚄 FASTJSON2 is a Java JSON library with excellent performance.
Apache License 2.0
3.79k stars 495 forks source link

[BUG]嵌套解析字段值不能是数值 #2982

Open JoJoJotarou opened 1 month ago

JoJoJotarou commented 1 month ago

问题描述

简要描述您碰到的问题。

环境信息

请填写以下信息:

重现步骤

如何操作可以重现该问题:

  1. 使用 main 方法
  2. condition: 100 时报错,condition: "100"正常,即condition 不能是数值
  3. 出现 ... 错误

    public class fastjson {
    
    public static void main(String[] args) {
        String json1 = "{ \n" +
                "  \"key\": \"1721210291174\",\n" +
                "  \"type\": \"PARALLEL\",\n" +
                "  \"action\": [],\n" +
                "  \"priority\": 1,\n" +
                "  \"condition\": [\n" +
                "    {\n" +
                "      \"key\": 1704359623221,\n" +
                "      \"type\": \"AND\",\n" +
                "      \"action\": [{\"operator\": \"ASSIGNMENT\", \"leftOperand\": \"@@89\",  \"rightOperand\": 128}],\n" +
                "      \"priority\": 1,\n" +
                "      \"condition\": [\n" +
    
                "        { \"type\": \"LEAF\", \"action\": [], \"priority\": 3, \"condition\": 100 }\n" +
                "      ]\n" +
                "    },\n" +
                "    {\n" +
                "      \"key\": 1704359623221,\n" +
                "      \"type\": \"LEAF\",\n" +
                "      \"action\": [{\"operator\": \"ASSIGNMENT\", \"leftOperand\": \"@@89\",  \"rightOperand\": 328}, {\"operator\": \"ASSIGNMENT\", \"leftOperand\": \"@@89\",  \"rightOperand\": 428}],\n" +
                "      \"priority\": 2,\n" +
                "      \"condition\": {\"operator\": \"GE\", \"leftOperand\": \"@@89\",  \"rightOperand\": 281}\n" +
                "    }\n" +
                "  ]\n" +
                "}";
    
        // Rule rule1 = JSON.parseObject(json1, new TypeReference<Rule>() {
        // });
        Rule rule1 = JSON.parseObject(json1, Rule.class);
    
        System.out.println(rule1);
    }
    
    public static class ConditionDeserializer implements ObjectReader<Object> {
        @Override
        public Object readObject(JSONReader jsonReader, Type type, Object o, long l) {
            // 非叶子节点
            if (jsonReader.isArray()) {
                return jsonReader.readArray(Rule.class);
            } else if (jsonReader.isObject()) {
                // 如果是对象,则解析为 Rule
                return jsonReader.read(Expr.class);
            } else if (jsonReader.isNumber()) {
                // 如果是数字,直接返回数值
                return jsonReader.getNumber().longValue();
            } else if (jsonReader.isString()) {
                // 如果是字符串,直接返回字符串
                return jsonReader.readString();
            } else {
                throw new JSONException("Unsupported condition type:" + jsonReader.current());
            }
        }
    }
    
    @Data
    public static class Rule {
        private String key;
        private String type;
        private Object action;
        private int priority;
    
        // Condition 可以是三种类型:Rule、Expr、String 或 Integer
        @JSONField(deserializeUsing = ConditionDeserializer.class)
        private Object condition;
    
        public void setCondition(Object condition) {
            this.condition = condition;
        }
    }
    
    @Data
    public static class Expr {
        private Object leftOperand;
        private String operator;
        private Object rightOperand;
    }
    }

期待的正确结果

对您期望发生的结果进行清晰简洁的描述。

相关日志输出

Exception in thread "main" com.alibaba.fastjson2.JSONException: read field 'com.xinji.rt.configurable.fastjson$Rule.setCondition, offset 358, character 1, line 13, column 70, fastjson-version 2.0.53
{ 
  "key": "1721210291174",
  "type": "PARALLEL",
  "action": [],
  "priority": 1,
  "condition": [
    {
      "key": 1704359623221,
      "type": "AND",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 128}],
      "priority": 1,
      "condition": [
        { "type": "LEAF", "action": [], "priority": 3, "condition": 100 }
      ]
    },
    {
      "key": 1704359623221,
      "type": "LEAF",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 328}, {"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 428}],
      "priority": 2,
      "condition": {"operator": "GE", "leftOperand": "@@89",  "rightOperand": 281}
    }
  ]
}
    at com.alibaba.fastjson2.reader.FieldReaderObject.readFieldValue(FieldReaderObject.java:165)
    at com.alibaba.fastjson2.reader.ObjectReader5.readObject(ObjectReader5.java:366)
    at com.alibaba.fastjson2.JSON.parseObject(JSON.java:864)
    at com.xinji.rt.configurable.fastjson.main(fastjson.java:43)
Caused by: com.alibaba.fastjson2.JSONException: read field 'com.xinji.rt.configurable.fastjson$Rule.setCondition, offset 358, character 1, line 13, column 70, fastjson-version 2.0.53
{ 
  "key": "1721210291174",
  "type": "PARALLEL",
  "action": [],
  "priority": 1,
  "condition": [
    {
      "key": 1704359623221,
      "type": "AND",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 128}],
      "priority": 1,
      "condition": [
        { "type": "LEAF", "action": [], "priority": 3, "condition": 100 }
      ]
    },
    {
      "key": 1704359623221,
      "type": "LEAF",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 328}, {"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 428}],
      "priority": 2,
      "condition": {"operator": "GE", "leftOperand": "@@89",  "rightOperand": 281}
    }
  ]
}
    at com.alibaba.fastjson2.reader.FieldReaderObject.readFieldValue(FieldReaderObject.java:165)
    at com.alibaba.fastjson2.reader.ObjectReader5.readObject(ObjectReader5.java:366)
    at com.alibaba.fastjson2.JSONReader.readArray(JSONReader.java:2410)
    at com.xinji.rt.configurable.fastjson$ConditionDeserializer.readObject(fastjson.java:53)
    at com.alibaba.fastjson2.reader.FieldReaderObject.readFieldValue(FieldReaderObject.java:152)
    ... 3 more
Caused by: com.alibaba.fastjson2.JSONException: illegal fieldName input1, offset 358, character 1, line 13, column 70, fastjson-version 2.0.53
{ 
  "key": "1721210291174",
  "type": "PARALLEL",
  "action": [],
  "priority": 1,
  "condition": [
    {
      "key": 1704359623221,
      "type": "AND",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 128}],
      "priority": 1,
      "condition": [
        { "type": "LEAF", "action": [], "priority": 3, "condition": 100 }
      ]
    },
    {
      "key": 1704359623221,
      "type": "LEAF",
      "action": [{"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 328}, {"operator": "ASSIGNMENT", "leftOperand": "@@89",  "rightOperand": 428}],
      "priority": 2,
      "condition": {"operator": "GE", "leftOperand": "@@89",  "rightOperand": 281}
    }
  ]
}
    at com.alibaba.fastjson2.JSONReaderUTF16.readFieldNameHashCode(JSONReaderUTF16.java:1130)
    at com.alibaba.fastjson2.reader.ObjectReader5.readObject(ObjectReader5.java:336)
    at com.alibaba.fastjson2.JSONReader.readArray(JSONReader.java:2410)
    at com.xinji.rt.configurable.fastjson$ConditionDeserializer.readObject(fastjson.java:53)
    at com.alibaba.fastjson2.reader.FieldReaderObject.readFieldValue(FieldReaderObject.java:152)
    ... 7 more

附加信息

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

JoJoJotarou commented 1 month ago

应该用readIntXXXValue,被getNumber迷惑了,这个getNumber取得值也是错的。