Bon*_*Oak 5 actor rust rust-actix
我正在尝试使用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>`
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的:
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(())
})
});
}
Run Code Online (Sandbox Code Playgroud)
相关依赖版本:
[dependencies]
actix-web = "0.7"
actix = "0.7"
futures = "0.1"
Run Code Online (Sandbox Code Playgroud)
为了保留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(|_| ())
});
Run Code Online (Sandbox Code Playgroud)
为了:
std::io::Error易于使用。由于所有actix错误类型都实现了Error,因此也可以保留原始类型and_then()允许我提取尸体。当这个问题解决后, a map(move确保我们随身携带response)然后返回一个元组(response, body)请注意,localhost出于测试目的,我将您的主机名替换为,因为ipv4.canhasip.com目前无法解析外部的任何内容。
初步回答:
您确实应该提供更多有关此问题的背景信息。actix有不止一种请求类型。
您的初始对象 ( response) 是 a ClientResponse。调用body()它会返回一个MessageBody结构,这是您掉入的兔子洞的开始。这不是真正的身体,只是一个实现该Future特征的对象,一旦它运行完毕,它就会产生你想要的东西。
您需要以一种不那么麻烦的方式来执行此操作,但现在要说服自己这是问题的根源,而不是您的代码行,请尝试以下操作:
println!("{:?}", response.body().wait())
Run Code Online (Sandbox Code Playgroud)
调用wait()future 会阻塞当前线程,这就是为什么我说这是一种临时的、hacky 的方式来告诉你问题出在哪里。根据您可以使用的内容(如果您在某处有类似执行器的对象,或者能够返回执行的 future),您的实际解决方案将会有所不同。
| 归档时间: |
|
| 查看次数: |
4541 次 |
| 最近记录: |