将Claims字段反序列化为字符串会返回其他字符

问题描述 投票:1回答:3

我需要反序列化以下有效负载,特别是来自JSON对象的aud字段:

claims: Claims { 
    aud: One("CBr3zBlrKBbwmxOAM1avZQ=="), // 24 len
    // ...
}

[claims::aud是一个Aud枚举:

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
    One(String),
    Many(Vec<String>),
}

[当我尝试从String中获取serde_json::to_string()时,它返回另外两个字符,即开始和结束字符。

use serde_json::Result;

fn aud_from_json(data: &claims::Aud) -> Result<String> {
    let v = serde_json::to_string(&data)?;
    Ok(v.to_owned())
}
let aud = aud_from_json(&token_data.claims.aud)?;
log::debug!("aud field: {:?}\t aud field len({})", &aud, &aud.len());
$ aud field: "\"CBr3zBlrKBbwmxOAM1avZQ==\""         aud field len(26)

看来可能会有尾随的转义字符序列化到字符串中。有没有一种方法可以将aud字段返回为String,并且在没有多余字符的情况下进行了清理?例如"CBr3zBlrKBbwmxOAM1avZQ=="

rust escaping serde-json
3个回答
0
投票

您的问题源于对serde板条箱实际使用的方法的基本误解。特别是to_json()不会生成JSON fragment。它返回一个完整的,完全有效的可解析JSON文档。

将独立字符串表示为JSON的方式涉及将其用引号引起来,就像您将其作为字段的一部分一样。因此,您的字段包含"CBr3zBlrKBbwmxOAM1avZQ=="并不奇怪,其中两个其他字符是引号和结尾引号。

您可以通过在playground上进行检查来使自己相信这一点:

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
    One(String),
    Many(Vec<String>),
}

fn aud_from_json(data: &Aud) -> Result<String> {
    let v = serde_json::to_string(&data)?;
    Ok(v.to_owned())
}

#[test]
fn works() {
    let aud = Aud::One("CBr3zBlrKBbwmxOAM1avZQ==".to_string());
    let serialized = aud_from_json(&aud).unwrap();
    assert_eq!(aud_from_json(&aud).unwrap(), "\"CBr3zBlrKBbwmxOAM1avZQ==\"".to_string());
    let deser:Aud = serde_json::from_str(&serialized).unwrap();
    assert_eq!(aud, deser);
}

请注意,此单个字符串为足够,以唯一地标识为反序列化提供的enum的哪个变体,因为参数类型不同。

[如果您还有其他期望,则需要自己实现Deserialize。有关如何执行此操作的示例很多。

如果您不希望使用引号,那么您实际上根本不应该首先序列化为JSON,因为JSON中未引用的字符串文字在任何地方都无效。

[如果您担心双引号,那纯粹是因为您正在调用Debug。它们实际上不在String中,默认情况下Debug打印用引号引起来的字符串。


0
投票

[如果我正确理解了您对@SébastienRenauld的回答的回答,则您希望对Aud实例中包含的字符串进行base-64解码。这可以通过以下方式实现:

let aud = Aud::One("CBr3zBlrKBbwmxOAM1avZQ==".to_string());
if let Aud::One(code) = aud {
    let decoded = base64::decode(&code).unwrap();
    log::debug!("Decoded: {:?}", decoded);
}

playground


-1
投票

不要在调试模式下打印输出:在格式字符串中使用{}而不是{:?}

log::debug!("aud field: {}\t aud field len({})", &aud, &aud.len());
© www.soinside.com 2019 - 2024. All rights reserved.