rust 无法从StackAPI解析JSON:期望值”,行:1,列:1

c9qzyr3d  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(217)

我正在尝试从这个端点解析JSON:https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow
它看起来像这样:

{
"items": [
{
"badge_counts": {
"bronze": 27,
"silver": 14,
"gold": 0
},
"account_id": 17932441,
"is_employee": false,
"last_modified_date": 1677242400,
"last_access_date": 1682981080,
"reputation_change_year": 313,
"reputation_change_quarter": 29,
"reputation_change_month": 0,
"reputation_change_week": 10,
"reputation_change_day": 0,
"reputation": 2234,
"creation_date": 1583703647,
"user_type": "registered",
"user_id": 13029516,
"website_url": "https://matthewtrent.me/links",
"link": "https://stackoverflow.com/users/13029516/matthew-trent",
"profile_image": "https://lh3.googleusercontent.com/a/AATXAJwHVeuBCVo52xa3k_IryQ1llGDNWkHRYiO0R2xh=k-s256",
"display_name": "Matthew Trent"
}
],
"has_more": false,
"quota_max": 300,
"quota_remaining": 271
}

但我做不到我使用的是reqwest包。下面是我使用它的端点(简化):

#[get("/test")]
async fn my_function(username: web::Query<QueryParams>) -> impl Responder {
    println!("recieved!");

    match reqwest
        ::get("https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow")
    .await
    {
        Ok(response) => {
            if response.status() != 200 {
                return HttpResponse::InternalServerError().finish();
            } else {
                let res = response.json::<serde_json::Value>().await.unwrap(); // <-- where it panics
                println!("Success! {:?}", res);
            }
        }
        Err(_) => return HttpResponse::InternalServerError().finish(),
    };
    HttpResponse::Ok().finish()
}

它在let res = response.json::<serde_json::Value>().await.unwrap();这一行出现恐慌。奇怪的是,我碰到了不同的端点(例如:https://pokeapi.co/api/v2/pokemon/ditto),它工作得很好,并列出了JSON结果。我唯一的猜测是Stack API没有正确格式化JSON?
下面是对https://api.stackexchange.com/2.2/users/13029516?&site=stackoverflow运行时的输出:

recieved!
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
recieved!
thread 'actix-rt|system:0|arbiter:1' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:2' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:3' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:4' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:5' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:6' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:7' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70
recieved!
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode, source: Error("expected value", line: 1, column: 1) }', src/services/stack_overflow.rs:42:70

任何帮助将是伟大的,谢谢。
1

2o7dmzc5

2o7dmzc51#

这是因为the Stack Exchange API does not follow the HTTP spec exactly
虽然我们的API是基于HTTP的,但我们选择在一个特定领域与标准HTTP不同。在正常操作期间,我们保证所有响应都被压缩,无论是GZIP还是DEFLATE。
如果检查请求和响应头,您将看到API返回Content-Encoding: gzip,尽管reqwest没有发送包含gzipAccept-Encoding
Reqwest决定忽略未知的编码,无论如何都要尝试读取它,结果导致垃圾数据。
幸运的是,您可以启用reqwest的gzip特性,这样它就可以发送Accept-Encoding: gzip报头并解码GZIP编码的响应。如果您想使用DEFLATE,还有一个deflate功能。

[dependencies]
reqwest = { verson = "0.11", features = ["json", "gzip", "deflate"] }

您还可以在运行时使用ClientBuilder::gzip方法关闭此行为。

相关问题