开发避坑指南(69):FastJSON 解析非标准 JSON 数据异常排查与解决方案

异常背景

在使用fastjson/fastjson2解析以下json数据的时候报错。

json数据

{
    "code": "0000",
    "data": [
        {
            "msg": "创建订单成功",
            "code": 325,
            "orderNO": "563225463214723",
            "tkNumber": "36235423157",
            "bmInfo": [
                [
                    {
                        "recetFdmc": "",
                        "mcInfos": {
                            "PRI": {
                                "value": {
                                    "priConfig": [
                                        0,
                                        1
                                    ]
                                }
                            }
                        },
                        "batch_code": "C200000",
                        "acc_phone": "",
                        "warse_no": ""
                    },
                    [
                        "32321",
                        "1323"
                    ]
                ]
            ]
        },
        {
            "msg": "创建订单成功",
            "code": 325,
            "orderNO": "563225463214724",
            "tkNumber": "36235423158",
            "bmInfo": [
                [
                    {
                        "recetFdmc": "",
                        "mcInfos": {
                            "PRI": {
                                "value": {
                                    "priConfig": [
                                        0,
                                        1
                                    ]
                                }
                            }
                        },
                        "batch_code": "M200000",
                        "acc_phone": "",
                        "warse_no": ""
                    },
                    [
                        "32321",
                        "1323"
                    ]
                ]
            ]
        }
    ],
    "message": "请求成功",
    "result": true,
}

报错信息

使用fastjson报错

Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, expect {, actual [, pos 275, fastjson-version 1.2.83
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:506)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:1624)
	at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_3_PdfInfo.deserialze(Unknown Source)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:287)
	at com.alibaba.fastjson.parser.DefaultJSONParser.parseArray(DefaultJSONParser.java:792)
	at com.alibaba.fastjson.serializer.CollectionCodec.deserialze(CollectionCodec.java:132)
	at com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer.parseArray(ArrayListTypeFieldDeserializer.java:185)
	at com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer.parseField(ArrayListTypeFieldDeserializer.java:71)

使用fastjson2报错

expect {, but [, class com.xxx.xxx, parent fieldName bmInfo, offset 142, character [, line 1, column 143, fastjson-version 2.0.34 

解析代码

ApiResponse apiResponse = JSON.parseObject(ret, ApiResponse.class);

相关实体

根据json结构创建对应实体类

@Getter
@Setter
public class ApiResponse {
    private String code;
    private List<OrderData> data;
    private String message;
    private Boolean result;
    private String sub_code;
    private String sub_msg;
}

@Getter
@Setter
public class OrderData {
    private String msg;
    private Integer code;
    private String orderNO;
    private String tkNumber;
    private List<List<JsonData>> bmInfo;
    //private List<List<Object>> bmInfo;
}

@Getter
@Setter
public class JsonData {
    private String recetFdmc;
    private McInfos mcInfos;
    private String batch_code;
    private String acc_phone;
    private String warse_no;
}

@Getter
@Setter
class McInfos {
    private PRI PRI;
}

@Getter
@Setter
class PRI {
    private Value value;
}

@Getter
@Setter
class Value {
    private List<Integer> priConfig;
}

异常分析

使用fastjson和fastjson2解析都报错了,说明不是fastjson版本的问题。

从fastjson2解析时的报错信息看,在解析bmInfo节点时出错,期望‌左花括号 {(表示JSON对象的开始,实际‌左方括号 [(表示JSON数组的开始)。

仔细看bmInfo节点的数据结构,这并不是标准的JSON格式‌,在数组内部混合了对象 {} 和数组 [] 类型。这种混合结构虽然在JSON解析器中可以解析,但不符合JSON的最佳实践,所以用fastjson工具解析报错了。

解决办法

对于bmInfo节点的解析,不能使用List<List> 类型的对象去接收,应该改成List<List>类型的对象,示例代码如下:

public class JsonFileParser {

    public static void main(String[] args) {
        try {
            // 接口返回的json字符串
            String ret="json字符串";
			ApiResponse apiResponse = JSON.parseObject(ret, ApiResponse.class);

            // 输出解析结果摘要
            System.out.println("=== JSON解析结果 ===");
            System.out.println("响应状态码: " + response.getCode());
            System.out.println("响应消息: " + response.getMessage());
            System.out.println("请求结果: " + response.getResult());
            System.out.println("订单数量: " + response.getData().size());
            System.out.println();

            // 详细遍历每个订单信息
            int orderIndex = 1;
            for (OrderData order : response.getData()) {
                System.out.println("订单 " + orderIndex + ":");
                System.out.println("  订单号: " + order.getOrderNO());
                System.out.println("  运单号: " + order.getTkNumber());
                System.out.println("  消息: " + order.getMsg());
                System.out.println("  状态码: " + order.getCode());

                // 处理bmInfo复杂结构
                if (order.getBmInfo() != null && !order.getBmInfo().isEmpty()) {
                    System.out.println("  批量信息:");
                    for (List<Object> batchItem : order.getBmInfo()) {
                        for (Object item : batchItem) {
                            if (item instanceof Map) {
                                // 处理对象类型数据
                                Map<String, Object> batchDetail = (Map<String, Object>) item;
                                System.out.println("    批次代码: " + batchDetail.get("batch_code"));
                                System.out.println("    收货电话: " + batchDetail.get("acc_phone"));

                                // 处理mcInfos嵌套结构
                                Map<String, Object> mcInfos = (Map<String, Object>) batchDetail.get("mcInfos");
                                if (mcInfos != null && mcInfos.containsKey("PRI")) {
                                    Map<String, Object> priInfo = (Map<String, Object>) mcInfos.get("PRI");
                                    Map<String, Object> valueInfo = (Map<String, Object>) priInfo.get("value");
                                    List<Integer> priConfig = (List<Integer>) valueInfo.get("priConfig");
                                    System.out.println("    隐私配置: " + priConfig);
                                }
                            } else if (item instanceof List) {
                                // 处理数组类型数据
                                List<Object> arrayData = (List<Object>) item;
                                System.out.println("    附加数据: " + arrayData);
                            }
                        }
                    }
                }
                System.out.println();
                orderIndex++;
            }

        } catch (IOException e) {
            System.err.println("解析JSON文件时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帧栈

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值