0

为了支持application/jsonmultipart/form-data在同一个 URL 上,我想检查“Content-Type”标头并选择一个合适的Data<T>类型来提交.dataApp::new.

如果我取消注释该.guard行,则将curl -X POST -H "Content-Type: multipart/form-data" -F files=\"qqq\" localhost:8080/upload被删除。但如果没有这.guard条线,一切都会按预期进行。怎么了?

HttpServer::new(move || {
    App::new()
        .service(resource("/upload")
     // .guard(actix_web::guard::Header("Content-Type", "multipart/form-data"))
        .data(form.clone())
        .route(post()
        .to(upload_multipart)
        )   
    )
})

如何在一个 App 实例中正确加入它们?

4

1 回答 1

0

目前,actix-web 1.0.3不支持 multipart/form-data,但您可以使用actix_multipart。由于重点是反序列化具有不同内容类型的相同数据,因此我已简化为使用application/x-www-form-urlencoded.

要支持两种不同的内容类型,请为每个处理程序嵌套web::resource并添加保护:

web::resource("/")
    .route(
        web::post()
            .guard(guard::Header(
                "content-type",
                "application/x-www-form-urlencoded",
            ))
            .to(form_handler),
    )
    .route(
        web::post()
            .guard(guard::Header("content-type", "application/json"))
            .to(json_handler),
    ),

创建接受反序列化数据的处理程序,并将数据发送到公共处理程序:

fn form_handler(user: web::Form<User>) -> String {
    handler(user.into_inner())
}

fn json_handler(user: web::Json<User>) -> String {
    handler(user.into_inner())
}

fn handler(user: User) -> String {
    format!("Got username: {}", user.username)
}

结果:

$ curl -d 'username=adsf' localhost:8000
Got username: asdf⏎
$ curl -d '{"username": "asdf"}' localhost:8000
Parse error⏎
$ curl -d '{"username": "asdf"}' -H 'content-type: application/json' localhost:8000
Got username: asdf⏎

要创建自己的反序列化器,请实现FromRequesttrait。

于 2019-07-09T14:41:44.473 回答