应用场景

现在我要调取第三方API获得相应的数据
现在接口可以正常调通并获取到json
(起初是对照接口文档写的代码,但是一直报错500,然后改了好多代码,很害怕是因为自己的代码没写好才这样的,最后还是去问同事了,同事说可能是参数缺失,又帮我要了postman链接,对比之后发现不一样的参数居多!!!!!甚至连url都不一样啊啊啊啊啊啊。可恶,为什么开发的时候还要面对这种问题,可恶的“假材料”!!!!)
以下是将获取到的JSON数据转换为TollExitRecordVO类的相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 解析成功的响应数据
JSONArray msgContent = jsonObject.getJSONArray("msgContent");
if (msgContent != null && !msgContent.isEmpty()) {
// 遍历msgContent数组,解析每一条数据
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

for (int i = 0; i < msgContent.size(); i++) {
JSONObject vehicleData = msgContent.getJSONObject(i);

TollExitRecordVO record = new TollExitRecordVO();

// 解析每一条记录并填充到TollExitRecordVO对象
record.setPassTime(LocalDateTime.parse(vehicleData.getStr("passtime"), formatter));
record.setEnTime(LocalDateTime.parse(vehicleData.getStr("entime"), formatter));
record.setVehicleType(vehicleData.getInt("vehicletype"));
record.setGantryName(vehicleData.getStr("gantryname"));
record.setVehicleClass(vehicleData.getInt("vehicleclass"));
record.setGantryType(vehicleData.getInt("gantrytype"));
record.setVehiclePlate(vehicleData.getStr("vlp"));
record.setVehiclePlateColor(vehicleData.getInt("vlpc"));
record.setEnTollStationIdName(vehicleData.getStr("entollstationname"));

records.add(record); // 将每一条记录加入到列表中
}
} else {
log.warn("没有查询到车辆信息");
}
return R.ok(records); // 返回所有解析后的记录

问题描述

运行上述代码后,程序抛出了NullPointerException:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"msgType":"ARR",
"msgContent":[
{
"vehicletype":"1",
"vehicleclass":"0",
"entollstationname1":"修水站",
"passtime":"2025-02-01T08:21:43",
"entime":"2025-02-01T08:21:43",
"vlp":"京A88888",
"vlpc":"0",
"entollstationname":"修水站"
},
{
"vehicletype":"1",
"vehicleclass":"0",
"entollstationname1":"兴国东站",
"passtime":"2025-02-01T12:47:46",
"entime":"2025-02-01T12:47:46",
"vlp":"京A88888",
"vlpc":"0",
"entollstationname":"兴国东站"
}
],
"msgDes":"QUERY",
"msgState":"SUCCESS"
}

Exception in thread "main" java.lang.NullPointerException: text
at java.util.Objects.requireNonNull(Objects.java:228)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1848)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at com.dhc.traffic.approve.utils.ThirdApiUtils.getTollEntryRecord(ThirdApiUtils.java:245)
at com.dhc.traffic.approve.utils.ThirdApiUtils.main(ThirdApiUtils.java:171)

从堆栈信息可以看出,NullPointerException 发生在以下代码行:

1
record.setPassTime(LocalDateTime.parse(vehicleData.getStr("passTime"), formatter));

报错信息提示 NullPointerException,说明 vehicleData.getStr(“passTime”) 返回了 null,然后在 LocalDateTime.parse() 中调用时发生了空指针异常

为什么从json里来看,passtime和entime都是有值的,但是获取到的结果为null呢?

解决方案

修改代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 解析成功的响应数据
JSONArray msgContent = jsonObject.getJSONArray("msgContent");
if (msgContent != null && !msgContent.isEmpty()) {
// 遍历msgContent数组,解析每一条数据
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

for (int i = 0; i < msgContent.size(); i++) {
JSONObject vehicleData = msgContent.getJSONObject(i);

TollEntryRecordVO record = new TollEntryRecordVO();

// 获取 passTime 字段
String passTimeStr = vehicleData.getStr("passtime");
log.debug("获取到的 passTime: '{}'", passTimeStr); // 打印 passTime 字符串

if (passTimeStr != null && !passTimeStr.isEmpty()) {
try {
passTimeStr = passTimeStr.trim(); // 去除空格
record.setPassTime(LocalDateTime.parse(passTimeStr, formatter));
} catch (DateTimeParseException e) {
log.error("解析时间失败: " + passTimeStr, e);
record.setPassTime(LocalDateTime.now()); // 设置默认时间
}
} else {
log.warn("passTime 为 null 或空字符串,跳过此记录");
record.setPassTime(LocalDateTime.now()); // 设置默认时间
}

// 获取 enTime 字段
String enTimeStr = vehicleData.getStr("entime");
log.debug("获取到的 enTime: '{}'", enTimeStr); // 打印 enTime 字符串

if (enTimeStr != null && !enTimeStr.isEmpty()) {
try {
enTimeStr = enTimeStr.trim(); // 去除空格
record.setEnTime(LocalDateTime.parse(enTimeStr, formatter));
} catch (DateTimeParseException e) {
log.error("解析时间失败: " + enTimeStr, e);
record.setEnTime(LocalDateTime.now()); // 设置默认时间
}
} else {
log.warn("enTime 为 null 或空字符串,跳过此记录");
record.setEnTime(LocalDateTime.now()); // 设置默认时间
}

// 解析每一条记录并填充到TollEntryRecordVO对象
// record.setPassTime(LocalDateTime.parse(vehicleData.getStr("passtime"), formatter));
record.setEnTollStationName1(vehicleData.getStr("entollstationname1"));
record.setVehicleClass(vehicleData.getInt("vehicleclass"));
record.setVehicleType(vehicleData.getInt("vehicletype"));
record.setVehiclePlateColor(vehicleData.getInt("vlpc"));
record.setVehiclePlate(vehicleData.getStr("vlp"));
record.setEnTollStationName(vehicleData.getStr("entollstationname"));
// record.setEnTime(LocalDateTime.parse(vehicleData.getStr("enTime"), formatter));

records.add(record); // 将每一条记录加入到列表中
}
} else {
log.warn("没有查询到车辆信息");
}
return R.ok(records); // 返回所有解析后的记录
}
}

// 如果超过最大重试次数仍然没有成功,则返回空列表
return R.failed("查询失败");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
"msgType":"ARR",
"msgContent":[
{
"vehicletype":"1",
"vehicleclass":"0",
"entollstationname1":"江西兴国东站",
"passtime":"2025-02-01T12:47:46",
"entime":"2025-02-01T12:47:46",
"vlp":"赣GUV822",
"vlpc":"0",
"entollstationname":"江西兴国东站"
},
{
"vehicletype":"1",
"vehicleclass":"0",
"entollstationname1":"江西修水站",
"passtime":"2025-02-01T08:21:43",
"entime":"2025-02-01T08:21:43",
"vlp":"赣GUV822",
"vlpc":"0",
"entollstationname":"江西修水站"
}
],
"msgDes":"QUERY",
"msgState":"SUCCESS"
}
11:26:52.541 [main] DEBUG com.dhc.traffic.approve.utils.ThirdApiUtils - 获取到的 passTime: '2025-02-01T12:47:46'
11:26:52.545 [main] DEBUG com.dhc.traffic.approve.utils.ThirdApiUtils - 获取到的 enTime: '2025-02-01T12:47:46'
11:26:52.546 [main] DEBUG com.dhc.traffic.approve.utils.ThirdApiUtils - 获取到的 passTime: '2025-02-01T08:21:43'
11:26:52.546 [main] DEBUG com.dhc.traffic.approve.utils.ThirdApiUtils - 获取到的 enTime: '2025-02-01T08:21:43'
请求成功,返回的数据如下:
TollEntryRecordVO(vehicleType=1, vehicleClass=0, enTollStationName1=江西兴国东站, passTime=2025-02-01T12:47:46, enTime=2025-02-01T12:47:46, vehiclePlate=赣GUV822, vehiclePlateColor=0, enTollStationName=江西兴国东站)
TollEntryRecordVO(vehicleType=1, vehicleClass=0, enTollStationName1=江西修水站, passTime=2025-02-01T08:21:43, enTime=2025-02-01T08:21:43, vehiclePlate=赣GUV822, vehiclePlateColor=0, enTollStationName=江西修水站)