actix-web app_data 在请求处理程序中总是 None
actix-web app_data is always None in request handler
我想在配置 Actix http 服务器时注册应用程序级数据,但是当我尝试使用 HttpRequest::app_data()
访问请求处理程序中的数据时,我总是得到 None
。下面的代码在 expect
语句的 index
请求处理程序中发生恐慌。
但是,如果我使用 String
而不是我的 TestData
结构,它确实有效。
我做错了什么?
我的cargo.toml:
[...]
[dependencies]
actix-web = "3.0"
log = "0.4"
env_logger = "0.9"
我的代码:
use actix_web::{middleware, web, HttpRequest, Result, Responder, HttpResponse};
use actix_web::{App, HttpServer};
use std::sync::Arc;
#[macro_use]
extern crate log;
extern crate env_logger;
struct TestData {
host: String
}
pub async fn index(req: HttpRequest) -> impl Responder {
let td: &TestData = req.app_data().expect("Test data missing in request handler.");
td.host.clone()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG",
format!("actix_server={log_level},actix_web={log_level}",
log_level="DEBUG"));
env_logger::init();
let server_data = web::Data::new(
TestData {
host: "Dadada".to_string(),
}
);
HttpServer::new(move || {
App::new()
.app_data(server_data.clone())
.route("/", web::get().to(index))
.wrap(middleware::Logger::default())
})
.bind("127.0.0.1:8080")?
.run()
.await
}
您需要使用 turbo fish 语法将 Data<T>
类型指定为 app_data
。
pub async fn index(req: HttpRequest) -> impl Responder {
let td: &TestData = req.app_data::<web::Data<TestData>>().expect("Test data missing in request handler.");
td.host.clone()
}
如果您查看 HttpRequest::app_data
定义,您会发现 app_data
需要此信息来消除 get
调用
的歧义
pub fn app_data<T: 'static>(&self) -> Option<&T> {
for container in self.0.app_data.iter().rev() {
//Used here ------------------------\/
if let Some(data) = container.get::<T>() {
return Some(data);
}
}
None
}
如果你只给编译器td
类型(td: &TestData
)。应用强制,编译器将推断出 T
遵守 T: 'static
绑定,但它不会是您想要的 T
(web::Data<TestData>
)。
我想在配置 Actix http 服务器时注册应用程序级数据,但是当我尝试使用 HttpRequest::app_data()
访问请求处理程序中的数据时,我总是得到 None
。下面的代码在 expect
语句的 index
请求处理程序中发生恐慌。
但是,如果我使用 String
而不是我的 TestData
结构,它确实有效。
我做错了什么?
我的cargo.toml:
[...]
[dependencies]
actix-web = "3.0"
log = "0.4"
env_logger = "0.9"
我的代码:
use actix_web::{middleware, web, HttpRequest, Result, Responder, HttpResponse};
use actix_web::{App, HttpServer};
use std::sync::Arc;
#[macro_use]
extern crate log;
extern crate env_logger;
struct TestData {
host: String
}
pub async fn index(req: HttpRequest) -> impl Responder {
let td: &TestData = req.app_data().expect("Test data missing in request handler.");
td.host.clone()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG",
format!("actix_server={log_level},actix_web={log_level}",
log_level="DEBUG"));
env_logger::init();
let server_data = web::Data::new(
TestData {
host: "Dadada".to_string(),
}
);
HttpServer::new(move || {
App::new()
.app_data(server_data.clone())
.route("/", web::get().to(index))
.wrap(middleware::Logger::default())
})
.bind("127.0.0.1:8080")?
.run()
.await
}
您需要使用 turbo fish 语法将 Data<T>
类型指定为 app_data
。
pub async fn index(req: HttpRequest) -> impl Responder {
let td: &TestData = req.app_data::<web::Data<TestData>>().expect("Test data missing in request handler.");
td.host.clone()
}
如果您查看 HttpRequest::app_data
定义,您会发现 app_data
需要此信息来消除 get
调用
pub fn app_data<T: 'static>(&self) -> Option<&T> {
for container in self.0.app_data.iter().rev() {
//Used here ------------------------\/
if let Some(data) = container.get::<T>() {
return Some(data);
}
}
None
}
如果你只给编译器td
类型(td: &TestData
)。应用强制,编译器将推断出 T
遵守 T: 'static
绑定,但它不会是您想要的 T
(web::Data<TestData>
)。