【问题标题】:actix-web app_data is always None in request handleractix-web app_data 在请求处理程序中始终为 None
【发布时间】:2021-11-29 06:05:07
【问题描述】:

我想在配置 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
}

【问题讨论】:

    标签: rust actix-web


    【解决方案1】:

    您需要使用turbo fish语法将Data&lt;T&gt;类型指定为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: &amp;TestData)。应用强制转换,编译器将推断出遵循 T: 'static 界限的 T,但它不会是您想要的 T (web::Data&lt;TestData&gt;)。

    【讨论】:

    • 搞定了,谢谢。我只是想知道为什么编译器不告诉我...
    猜你喜欢
    • 1970-01-01
    • 2022-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多