[已解决] HttpMessageNotReadableException: JSON parse error: Unexpected character
文章目录
- 写在前面
- 问题描述
- 报错原因分析:
- 解决思路
- 解决办法
- 1. 检查并修复客户端的 JSON 数据格式
- 2. 确认请求头的 Content-Type 设置正确
- 3. 捕获并处理 HttpMessageNotReadableException 异常
- 4. 校验客户端传递的数据是否是 JSON
- 5. 确保客户端和服务端使用相同的字符编码
- 6. 检查网络传输问题
- 总结
写在前面
在使用 Spring MVC 或 Spring Boot 进行 API 开发时,当客户端向服务端发送无效的 JSON 数据时,可能会抛出如下异常:
HttpMessageNotReadableException: JSON parse error: Unexpected character
该异常通常表示传递给服务器的 JSON 数据格式错误,导致服务器无法解析。本文将对此问题进行深入分析,并提供详细的解决方案。
问题描述
报错代码行:
HttpMessageNotReadableException: JSON parse error: Unexpected character
报错原因分析:
- 无效的 JSON 格式:客户端请求的 JSON 数据存在语法错误,例如缺少引号、逗号或括号。
- 字符编码错误:客户端使用了错误的字符集,导致服务端无法正确解析数据。
- 传递了非 JSON 数据:如果客户端发送的请求数据不是有效的 JSON(如普通文本、XML 等),也会触发此异常。
- Content-Type 错误:请求头中的
Content-Type
不是application/json
,导致服务器尝试以错误的格式解析数据。 - 数据传输中损坏:网络传输问题导致部分数据丢失或损坏,导致 JSON 数据无法正常解析。
解决思路
- 检查 JSON 格式:首先检查客户端传递的 JSON 数据格式是否正确,确保其符合标准 JSON 格式。
- 确认字符编码:确保客户端和服务器都使用了相同的字符集,常用的是
UTF-8
。 - 验证请求头 Content-Type:确保请求头的
Content-Type
设置为application/json
。 - 处理非 JSON 数据:如果客户端发送的不是 JSON 数据,需要在服务器端添加数据格式校验,防止发送非 JSON 格式时直接抛出异常。
- 捕获并处理异常:在服务端捕获该异常并返回明确的错误信息给客户端,提示其检查请求数据格式。
解决办法
1. 检查并修复客户端的 JSON 数据格式
当遇到此类错误时,首先应该检查客户端发送的 JSON 数据是否格式正确。常见的错误包括:
- 缺少或多余的引号:
{name: "John", age: 30} // 错误,键 "name" 需要引号 {"name": "John", "age": 30} // 正确
- 缺少逗号或多余的逗号:
{"name": "John" "age": 30} // 错误,两个键之间缺少逗号 {"name": "John", "age": 30} // 正确
使用在线的 JSON 校验工具(如 JSONLint)来校验 JSON 数据的正确性。
2. 确认请求头的 Content-Type 设置正确
确保客户端发送的请求头中包含以下内容:
Content-Type: application/json
如果 Content-Type 未设置为 application/json
,服务端可能尝试使用其他格式来解析请求数据,从而导致解析失败。可以通过以下代码在请求中设置正确的 Content-Type:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'John', age: 30 })
});
3. 捕获并处理 HttpMessageNotReadableException 异常
为了防止在解析 JSON 数据时抛出未处理的异常,建议在服务端捕获 HttpMessageNotReadableException
,并返回自定义的错误信息。可以在 Spring Boot 的控制器类中使用 @ExceptionHandler
来捕获并处理该异常:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) {
String errorMessage = "Invalid JSON format: " + ex.getMessage();
return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
}
}
这将返回更加友好的错误信息,并引导客户端检查他们的请求数据格式。
4. 校验客户端传递的数据是否是 JSON
如果存在客户端可能传递非 JSON 数据的情况,可以在服务端增加数据校验逻辑,确保接收到的请求数据是 JSON 格式。可以使用以下代码在处理请求之前验证其是否为合法的 JSON:
public boolean isValidJson(String json) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(json);
return true;
} catch (IOException e) {
return false;
}
}
5. 确保客户端和服务端使用相同的字符编码
客户端和服务端应确保使用相同的字符集进行数据传输,通常为 UTF-8
。可以在 Spring Boot 中通过以下配置强制设置字符编码:
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
6. 检查网络传输问题
如果确认客户端 JSON 数据格式正确且服务器配置无误,仍然出现该错误,可能是网络传输中数据被损坏。可以使用网络抓包工具(如 Wireshark)检查数据是否在传输过程中被修改或截断。
总结
HttpMessageNotReadableException
异常通常是由于客户端传递了无效的 JSON 数据或请求头配置错误引起的。通过检查 JSON 数据格式、确认请求头设置、捕获并处理异常等措施,可以有效解决该问题并改善客户端与服务器的交互体验。