7

我正在使用 Actix 框架来创建一个简单的服务器,并且我已经使用一个简单的 HTML 前端实现了文件上传。

use actix_web::web::Data;
use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use std::cell::Cell;

// file upload functions, the same as you can find it under the 
// actix web documentation:
// https://github.com/actix/examples/blob/master/multipart/src/main.rs :
mod upload; 


fn index() -> HttpResponse {
    let html = r#"<html>
            <head><title>Upload Test</title></head>
            <body>
                <form target="/" method="post" enctype="multipart/form-data">
                    <input type="file" name="file"/>
                    <input type="submit" value="Submit"></button>
                </form>
            </body>
        </html>"#;

    HttpResponse::Ok().body(html)
}

#[derive(Clone)]
pub struct AppState {        
    counter: Cell<usize>,        
}

impl AppState {
    fn new() -> Result<Self, Error> {
        // some stuff
        Ok(AppState {
            counter: Cell::new(0usize),
        })
    }
}
fn main() {

    let app_state = AppState::new().unwrap();

    println!("Started http server: http://127.0.0.1:8000");

    HttpServer::new(move || {
        App::new()
            .wrap(middleware::Logger::default())
            .service(
                web::resource("/")
                    .route(web::get().to(index))
                    .route(web::post().to_async(upload::upload)),
            )
            .data(app_state.clone())
    })
    .bind("127.0.0.1:8000")
    .unwrap()
    .run()
    .unwrap();
}

运行服务器工作正常,但是当我提交文件上传时,它说:

应用数据未配置,配置使用 App::data()

我不知道该怎么办。

4

5 回答 5

4

我请 rust-jp 社区的人告诉你正确答案。

使用Arc外部HttpServer.

/*
~~~Cargo.toml
[package]
name = "actix-data-example"
version = "0.1.0"
authors = ["ncaq <ncaq@ncaq.net>"]
edition = "2018"

[dependencies]
actix-web = "1.0.0-rc"
env_logger = "0.6.0"
~~~
 */

use actix_web::*;
use std::sync::*;

fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=trace");
    env_logger::init();

    let data = Arc::new(Mutex::new(ActixData::default()));
    HttpServer::new(move || {
        App::new()
            .wrap(middleware::Logger::default())
            .data(data.clone())
            .service(web::resource("/index/").route(web::get().to(index)))
            .service(web::resource("/create/").route(web::get().to(create)))
    })
    .bind("0.0.0.0:3000")?
    .run()
}

fn index(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
    println!("actix_data: {:?}", actix_data);
    HttpResponse::Ok().body(format!("{:?}", actix_data))
}

fn create(actix_data: web::Data<Arc<Mutex<ActixData>>>) -> HttpResponse {
    println!("actix_data: {:?}", actix_data);
    actix_data.lock().unwrap().counter += 1;
    HttpResponse::Ok().body(format!("{:?}", actix_data))
}

/// actix-webが保持する状態
#[derive(Debug, Default)]
struct ActixData {
    counter: usize,
}

这篇文章向上游报告。 官方文档数据原因App data is not configured, to configure use App::data()· Issue #874 · actix/actix-web

于 2019-05-30T07:47:06.513 回答
2

遇到了类似的错误:Internal Server Error: "App data is not configured, to configure use App::data()"

来自:https ://github.com/actix/examples/blob/master/state/src/main.rs

  1. 对于全局共享状态,我们将状态包装在 a 中actix_web::web::Data并将其移动到工厂闭包中。闭包被称为每个线程一次,我们克隆我们的状态并附加到Appwith的每个实例.app_data(state.clone())

因此:

impl AppState {
    fn new() -> actix_web::web::Data<AppState> {
        actix_web::web::Data<AppState> {
            counter: Cell::new(0usize),
        }
    }
}

...在工厂关闭中:

... skip ...
HttpServer::new(move || {
    App::new()
        .app_data(AppState::new().clone())
... skip ...
  1. 对于线程本地状态,我们在工厂闭包中构造我们的状态并使用.data(state).

因此:

... skip ...
HttpServer::new(move || {
    let app_state = Cell::new(0usize);
    App::new()
        .data(app_state)
... skip ...
于 2021-02-01T13:18:17.850 回答
1

代替:

App::data(app_state.clone())

你应该使用:

App::app_data(app_state.clone())
于 2021-01-31T06:33:42.583 回答
0

如果您调用具有与 HttpServer 应用程序数据不匹配的任何参数的函数,它将给您同样的错误。

例如,在这种情况下,&Client需要是Client.

pub fn index(client: web::Data<&Client>() {
// ...

}
于 2022-02-04T07:12:04.210 回答
-2

您必须先注册您的数据,然后才能使用它:

App::new().data(AppState::new())
于 2019-05-13T21:03:36.507 回答