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