Rust JSON反序列化失败求助:结构体与JSON格式匹配问题
Rust Serde反序列化失败排查方案
我是Rust新手,调用API获取到如下格式的JSON(以debug形式展示):
Array([ Object({ "columns": Array([ String( "attr", ), String( "user_count", ), ]), "data": Array([ Object({ "meta": Array([ Null, Null, ]), "row": Array([ Array([ String( "Built-in account for administering the computer/domain", ), ]), Number( 1, ), ]), }), ]), }), ])
我定义了对应的序列化结构体:
#[derive(Serialize, Deserialize, Debug)] pub struct ResolvedAttribute { pub columns: Vec<Option<String>>, pub data: Vec<MetaData>, } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct MetaData { pub meta: Vec<Option<String>>, pub row: (Vec<Vec<Option<String>>>, i64), }
执行反序列化代码时触发panic:
let res = REQWEST_MTLS.post(&uri).json(&req).send().await.unwrap(); //println!("res {:#?}", res); if !res.status().is_success() { let body: Value = res.json().await.unwrap(); println!("Error: {:#}", body); panic!(); } let res: Value = res.json().await.unwrap(); println!("res {:#?}", res); let root: Vec<ResolvedAttribute> = match serde_json::from_value(res.clone()) { Ok(r) => r, Err(e) => { println!("{:#}\nError:{:#?}", res, e); panic!("Deserialization Error."); } }; return root
错误信息:
thread 'main' panicked at 'Deserialization Error.
排查方向
1. 响应体被重复读取导致无数据可用
reqwest的Response是流式结构,只能被读取一次。你的代码中:
- 请求失败时,调用
res.json().await读取了响应体; - 请求成功时,再次调用
res.json().await,此时响应体已被消费,无法读取有效数据,直接引发反序列化失败。
修复方案:先完整读取并保存响应体,再进行后续处理:
let res = REQWEST_MTLS.post(&uri).json(&req).send().await.unwrap(); let status = res.status(); // 先读取响应体字节保存,避免重复读取 let body_bytes = res.bytes().await.unwrap(); if !status.is_success() { let body: Value = serde_json::from_slice(&body_bytes).unwrap(); println!("Error: {:#}", body); panic!(); } // 从保存的字节中解析JSON let res: Value = serde_json::from_slice(&body_bytes).unwrap(); println!("res {:#?}", res); let root: Vec<ResolvedAttribute> = match serde_json::from_value(res.clone()) { Ok(r) => r, Err(e) => { println!("{:#}\nError:{:#?}", res, e); panic!("Deserialization Error."); } }; return root
2. 打印完整的Serde错误信息
当前panic仅输出通用提示,未展示Serde的具体错误详情(如字段类型不匹配、数组长度不兼容等)。确保在错误分支中完整打印e的内容:
Err(e) => { println!("响应内容:\n{:#}\n反序列化错误详情:\n{:#?}", res, e); panic!("Deserialization Error."); }
通过具体错误信息可快速定位结构体与JSON格式不匹配的具体位置。
3. 核对结构体与JSON的类型匹配度
逐一校验字段定义:
columns:JSON中是["attr", "user_count"](非空字符串数组),结构体定义Vec<Option<String>>兼容,但可简化为Vec<String>(若确定无null值);row:JSON中是[[String], Number],结构体定义(Vec<Vec<Option<String>>>, i64),需确认JSON中row的第一个元素始终是嵌套数组,若为单层数组则需调整为(Vec<Option<String>>, i64);meta:JSON中是[Null, Null],结构体定义Vec<Option<String>>完全匹配,无问题。
内容的提问来源于stack exchange,提问作者JGilmartin
相关产品推荐
相关产品推荐

