1. 复现错误
今天写好导入hive表
的接口,如下代码所示:
/**
* hive表导入
*
* @author super先生
* @datetime 2023/3/20:16:32
* @return
*/
@ResponseBody
@PostMapping(value = "/xxx/importTables")
public ServiceStatusData localHiveImportTables(
@RequestBody ImportTablesBo importTablesBo,
@RequestHeader("x-userid") Long userId) {
logger.info("入参记录:importTablesBo={},userId={}", importTablesBo, userId);
if (isBlank(importTablesBo.getHiveTableName())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "hive表名不能为空", null);
}
if (isBlank(importTablesBo.getTableImportType())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "导表类型不能为空", null);
}
if (isBlank(importTablesBo.getCron())) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "执行周期表达式不能为空", null);
}
if (null == importTablesBo.getDatasetId()) {
return new ServiceStatusData(ServiceStatusData.Status.Fail, "工作表id不能为空", null);
}
// TODO 调用service层的方法
......
return new ServiceStatusData(ServiceStatusData.Status.Success, "", importTablesBo);
}
同时,使用Ajax
调用导入hive表
的接口,如下代码所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>content-type为application/json</title>
<script src="js/jquery-3.4.1.js"></script>
<script>
function importTables() {
const importTablesReq = {
"hiveTableName": "project",
"tableImportType": "1",
"pkColumn": "id",
"incrementColumn": "projectname",
"cron": "0 0 11 * * ?",
"datasetId": 2
};
$.ajax({
type: 'post',
headers: {
"x-userid": 1
},
data: importTablesReq,
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log("data=", data)
}
});
}
</script>
</head>
<body>
<button type="button" onclick="importTables()">点击按钮获取值</button>
</body>
</html>
启动项目后,使用chrome
浏览器测试,却报出如下错误:
即Could not read document: Unrecognized token 'hiveTableName': was expecting ('true', 'false' or 'null')\n at [Source: java.io.PushbackInputStream@2cf94db9; line: 1, column: 15];
的错误。
2. 分析错误
正赶上最近ChatGPT
比较火,可以借助它来帮我分析错误,如下图所示:
ChatGPT
说我的错误是由于JSON 解析器
无法识别hiveTableName
这个标记,这标记是实体类ImportTablesBo
的属性,也是Ajax
中的传参字段。
于是,使用postman
来测试后端代码,是否存在问题,如下图所示:
后端代码能够成功接收postman
的参数,也能够成功响应。
那么,由此可以断定,问题出现在前端代码中。
根据网上的资料可知:发送ajax
请求时,将js对象
进行json
字符串化处理,调用JSON.stringify()
函数将js对象
转换成字符串的格式发送到后台接口中。
于是检查我的上述Ajax
代码,果然没有使用JSON.stringify()
函数修饰importTablesReq
对象。
3. 解决错误
因为我的Ajax
代码,没有使用JSON.stringify()
函数修饰importTablesReq
对象。
因而,使用JSON.stringify()
函数修饰importTablesReq
对象即可,如下代码所示:
function importTables() {
const importTablesReq = {
"hiveTableName": "project",
"tableImportType": "1",
"pkColumn": "id",
"incrementColumn": "projectname",
"cron": "0 0 11 * * ?",
"datasetId": 2
};
$.ajax({
type: 'post',
headers: {
"x-userid": 1
},
data: JSON.stringify(importTablesReq),
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log("data=", data)
}
});
}
如是修改,便能成功调用导入hive表
的接口,如下图所示:
4. 文末总结
通过对Could not read document: Unrecognized token 'hiveTableName': was expecting ('true', 'false' or 'null')
错误的分析与解决,可以清楚地知道如何解决该类错误。
报出该类错误,即Could not read document: Unrecognized token 'xxx': was expecting ('true', 'false' or 'null')
, 这种情况一般是由于发送ajax
请求时,data
选项传入的数据参数类型错误。
当传入js
对象类型时会出现如上错误,因为springMVC
数据转换器无法解析并转换js对象
的属性值到 java对象
中,所以就会报以上异常错误。
因而,需要调用JSON.stringify()
函数将js对象
转换成字符串的格式发送到后台接口中,才能避免或解决这种错误。