Actix-Web 在处理文件上传时报告 "App data is not configured"
Actix-Web reports "App data is not configured" when processing a file upload
我正在使用 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 is not configured, to configure use App::data()
我不知道该怎么办。
您必须先注册您的数据才能使用它:
App::new().data(AppState::new())
我问了 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(app_state.clone())
你应该使用:
App::app_data(app_state.clone())
遇到类似错误:内部服务器错误:“应用程序数据未配置,配置使用 App::data()”
来自:https://github.com/actix/examples/blob/master/state/src/main.rs
- 对于全局共享状态,我们将我们的状态包装在
actix_web::web::Data
中并将其移动到工厂闭包中。闭包被称为每个线程一次,我们克隆我们的状态并附加到 App
的每个实例 .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 ...
- 对于线程本地状态,我们在工厂闭包中构造我们的状态并使用
.data(state)
附加到应用程序。
因此:
... skip ...
HttpServer::new(move || {
let app_state = Cell::new(0usize);
App::new()
.data(app_state)
... skip ...
如果您调用的函数有任何与 HttpServer 应用程序数据不匹配的参数,则会出现同样的错误。
例如,在这种情况下,&Client
需要是 Client
。
pub fn index(client: web::Data<&Client>() {
// ...
}
我正在使用 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 is not configured, to configure use App::data()
我不知道该怎么办。
您必须先注册您的数据才能使用它:
App::new().data(AppState::new())
我问了 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(app_state.clone())
你应该使用:
App::app_data(app_state.clone())
遇到类似错误:内部服务器错误:“应用程序数据未配置,配置使用 App::data()”
来自:https://github.com/actix/examples/blob/master/state/src/main.rs
- 对于全局共享状态,我们将我们的状态包装在
actix_web::web::Data
中并将其移动到工厂闭包中。闭包被称为每个线程一次,我们克隆我们的状态并附加到App
的每个实例.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 ...
- 对于线程本地状态,我们在工厂闭包中构造我们的状态并使用
.data(state)
附加到应用程序。
因此:
... skip ...
HttpServer::new(move || {
let app_state = Cell::new(0usize);
App::new()
.data(app_state)
... skip ...
如果您调用的函数有任何与 HttpServer 应用程序数据不匹配的参数,则会出现同样的错误。
例如,在这种情况下,&Client
需要是 Client
。
pub fn index(client: web::Data<&Client>() {
// ...
}