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序列化:
在你的数据类中添加一个返回字典的方法:
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") }发送请求时,直接将字典传给
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
相关产品推荐
相关产品推荐

