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

使用serde/serde_json反序列化时如何保留原始JSON字符串载荷?

serde_json反序列化保留完整原始JSON的实现方案

现有方案的问题

你当前采用的先转Value再序列化的方案有两个明显缺陷:

  • 存在额外的序列化/反序列化开销,数据量大时性能损耗明显
  • 序列化Value得到的字符串和原始输入不一致,会丢失原始的格式(空格、换行、字段顺序),不符合保留原始JSON的需求

最优实现方案

方案1:基于RawValue手动实现反序列化(推荐)

这个方案完全内置在反序列化流程中,自动保留原始JSON的所有格式,不需要外部手动传递原始字符串,同时适配普通字符串、流两种反序列化场景:

use serde::de::Deserializer;
use serde::{Deserialize, Serialize};
use serde_json::value::RawValue;

#[derive(Debug, Serialize)]
struct User {
    pub raw: String,
    pub id: u64,
    pub login: String,
}

impl<'de> Deserialize<'de> for User {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        // 读取整个JSON对象的原始字符串,几乎无性能开销
        let raw_json = <&'de RawValue>::deserialize(deserializer)?;
        // 反序列化其他业务字段
        #[derive(Deserialize)]
        struct UserInner {
            id: u64,
            login: String,
        }
        let inner: UserInner = serde_json::from_str(raw_json.get())
            .map_err(serde::de::Error::custom)?;
        
        Ok(Self {
            raw: raw_json.get().to_string(),
            id: inner.id,
            login: inner.login,
        })
    }
}

使用方式和普通反序列化完全一致:

let json_str = r#"{
  "id": 123,
  "login": "johndoe"
}"#;
let user: User = serde_json::from_str(json_str).unwrap();
// user.raw 就是完全和输入一致的原始JSON字符串

方案2:辅助函数封装(轻量适配)

如果你已经持有原始JSON字符串,不需要适配流反序列化场景,可以用更简单的辅助函数实现,无需修改结构体的默认派生逻辑:

#[derive(Debug, Serialize, Deserialize)]
struct User {
    #[serde(skip)]
    pub raw: String,
    pub id: u64,
    pub login: String,
}

fn deserialize_user(json_str: &str) -> Result<User, serde_json::Error> {
    let mut user: User = serde_json::from_str(json_str)?;
    user.raw = json_str.to_string();
    Ok(user)
}

这个方案代码量最少,没有任何额外性能开销,适合绝大多数普通场景使用。

内容的提问来源于stack exchange,提问作者Evaldas Buinauskas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:30:02