gpt4 book ai didi

rust - 将 actix_web 响应的主体提取到字符串中的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-29 08:02:46 28 4
gpt4 key购买 nike

我正在尝试使用 actix_web获取并显示网页的内容。 HTTP 请求成功完成,我可以查看网页,但我想将正文读入 String 以进行打印。

我试过 let my_ip: String = response.body().into(); 但我收到一条错误消息

error[E0277]: the trait bound `std::string::String: std::convert::From<actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>>` is not satisfied
--> src/main.rs:16:53
|
16 | let my_ip: String = response.body().into();
| ^^^^ the trait `std::convert::From<actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>>` is not implemented for `std::string::String`
|
= help: the following implementations were found:
<std::string::String as std::convert::From<&'a str>>
<std::string::String as std::convert::From<std::borrow::Cow<'a, str>>>
<std::string::String as std::convert::From<std::boxed::Box<str>>>
<std::string::String as std::convert::From<trust_dns_proto::error::ProtoError>>
= note: required because of the requirements on the impl of `std::convert::Into<std::string::String>` for `actix_web::httpmessage::MessageBody<actix_web::client::response::ClientResponse>`

这是我目前所拥有的:

use actix;
use actix_web::{client, HttpMessage};
use futures::future::Future;

fn main() {
actix::run(|| {
client::get("http://ipv4.canhasip.com/")
.header("User-Agent", "Actix-web")
.finish()
.unwrap()
.send()
.map_err(|_| ())
.and_then(|response| {
println!("Response: {:?}", response);
// error occurs here
let my_ip: String = response.body().into();
Ok(())
})
});
}

相关依赖版本:

[dependencies]
actix-web = "0.7"
actix = "0.7"
futures = "0.1"

最佳答案

为了在提取正文的同时保留您拥有的response 对象,我们将利用这一事实,与其他一些框架不同,您可以在不解构的情况下提取正文整个对象。代码如下:

actix::run(|| {

client::get("http://localhost/")
.header("User-Agent", "Actix-web")
.finish()
.unwrap()
.send()
.map_err(|e| {
Error::new(ErrorKind::AddrInUse, "Request error", e)
})
.and_then(|response| {
println!("Got response");
response.body().map(move |body_out| {
(response, body_out)
}).map_err(|e| Error::new(ErrorKind::InvalidData, "Payload error", e))
}).and_then(|(response, body)| {
println!("Response: {:?}, Body: {:?}", response, body);
Ok(())
}).map_err(|_| ())
});

按顺序:

  • 其中的所有内容现在都使用 std::io::Error 以便于使用。由于所有 actix 错误类型都实现了 Error,因此也可以保留原始类型
  • and_then() 允许我提取正文。解决此问题后,map(使用 move 确保我们正在接受 response)然后返回一个元组 (响应,正文)
  • 从那里,您可以根据需要自由使用响应或正文

请注意,出于测试目的,我用 localhost 替换了您的主机名,因为 ipv4.canhasip.com 目前无法解析外部的任何内容。


初始答案:

您真的应该就此提供更多背景信息。 actix 有不止一种请求类型。

您的初始对象(response)是一个 ClientResponse .对其调用 body() 会返回一个 MessageBody 结构,这是您掉入的兔子洞的起点。这不是实际的主体,只是一个实现Future 特性的对象,一旦它运行完它就会产生你想要的东西。

您需要以一种不那么骇人听闻的方式来执行此操作,但现在并说服自己这是问题的根源,而不是您的代码行,请尝试以下操作:

println!("{:?}", response.body().wait())

在 future 上调用 wait() 会阻塞当前线程,这就是为什么我说这是一种临时的、笨拙的方式来告诉你问题出在哪里。根据您可以使用的内容(如果您在某处有类似执行程序的对象,或者能够返回执行的 future ),您的实际解决方案会有所不同。

关于rust - 将 actix_web 响应的主体提取到字符串中的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54067451/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com