You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python requests发送JSON遭Spring Boot Jackson解析失败问题排查

问题分析与解决方案

核心原因

你遇到的400错误本质是:使用requests.post的json参数传入已经序列化好的JSON字符串时,requests会对这个字符串再做一次JSON序列化。最终发给服务器的不是预期的JSON对象,而是一个包裹着JSON字符串的字符串(比如"{\"start_date_time\":\"20240227-215731\",...}")。Spring Boot的Jackson解析器收到这个字符串后,尝试把它直接映射到Timer对象,自然会报错——因为它需要的是JSON对象,不是字符串。

解决方案

方案1:推荐——直接传递Python字典给json参数

放弃自定义的toJSON()方法(它返回的是序列化后的字符串),改成返回一个Python字典,让requests自动处理JSON序列化:

  1. 在你的数据类中添加一个返回字典的方法:

    def to_dict(self):
        return {
            "start_date_time": self.start_date_time.strftime("%Y%m%d-%H%M%S"),
            "channel": self.channel,
            "snr": self.snr,
            "dbfs": self.dbfs,
            "lat": self.lat,
            "lon": self.lon,
            # 补充其他字段
            "end_date_time": self.finish_date_time.strftime("%Y%m%d-%H%M%S")
        }
    
  2. 发送请求时,直接将字典传给json参数:

    import requests
    
    ct = ChickTimer(...)  # 你的实例化对象
    response = requests.post(your_server_url, json=ct.to_dict())
    

这种方式下,requests会自动将字典序列化为JSON字符串,并设置正确的Content-Type: application/json请求头,服务器收到的就是正常的JSON对象,Jackson可以正确解析。

方案2:使用已序列化的字符串(不推荐)

如果你坚持要用自定义toJSON()生成的字符串,需要用data参数传递,并手动设置请求头:

response = requests.post(
    your_server_url,
    data=ct.toJSON(),
    headers={"Content-Type": "application/json"}
)

这种方式需要自己确保字符串是合法的JSON,并且手动设置请求头,不如方案1简洁可靠。

对测试现象的解释

  • 测试1成功:Postman直接将你粘贴的JSON字符串作为请求体,自动设置了Content-Type: application/json,服务器收到的是JSON对象,解析正常。
  • 测试2失败:你构造的testjson是字符串,用json参数传递时被二次序列化,服务器收到的是包裹字符串的JSON,解析失败。
  • 测试3失败:直接传ChickTimer对象,requests无法序列化自定义类;传ct.toJSON()的结果(字符串),同样被二次序列化,导致服务器收到字符串包裹的JSON。
  • 测试4成功:用data参数传字符串时,requests不会修改内容,只要服务器能识别请求体的JSON格式(可能你隐式设置了正确的请求头,或者服务器做了兼容),就能正常解析。

内容的提问来源于stack exchange,提问作者Al Grant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 09:03:10