[已解决] HttpMessageNotReadableException: JSON parse error: Unexpected character

[已解决] HttpMessageNotReadableException: JSON parse error: Unexpected character

写在前面

在使用 Spring MVC 或 Spring Boot 进行 API 开发时,当客户端向服务端发送无效的 JSON 数据时,可能会抛出如下异常:

HttpMessageNotReadableException: JSON parse error: Unexpected character

该异常通常表示传递给服务器的 JSON 数据格式错误,导致服务器无法解析。本文将对此问题进行深入分析,并提供详细的解决方案。

在这里插入图片描述

问题描述

报错代码行:

HttpMessageNotReadableException: JSON parse error: Unexpected character

报错原因分析:

  1. 无效的 JSON 格式:客户端请求的 JSON 数据存在语法错误,例如缺少引号、逗号或括号。
  2. 字符编码错误:客户端使用了错误的字符集,导致服务端无法正确解析数据。
  3. 传递了非 JSON 数据:如果客户端发送的请求数据不是有效的 JSON(如普通文本、XML 等),也会触发此异常。
  4. Content-Type 错误:请求头中的 Content-Type 不是 application/json,导致服务器尝试以错误的格式解析数据。
  5. 数据传输中损坏:网络传输问题导致部分数据丢失或损坏,导致 JSON 数据无法正常解析。

解决思路

  1. 检查 JSON 格式:首先检查客户端传递的 JSON 数据格式是否正确,确保其符合标准 JSON 格式。
  2. 确认字符编码:确保客户端和服务器都使用了相同的字符集,常用的是 UTF-8
  3. 验证请求头 Content-Type:确保请求头的 Content-Type 设置为 application/json
  4. 处理非 JSON 数据:如果客户端发送的不是 JSON 数据,需要在服务器端添加数据格式校验,防止发送非 JSON 格式时直接抛出异常。
  5. 捕获并处理异常:在服务端捕获该异常并返回明确的错误信息给客户端,提示其检查请求数据格式。

解决办法

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 数据格式、确认请求头设置、捕获并处理异常等措施,可以有效解决该问题并改善客户端与服务器的交互体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

几何心凉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值