11 个版本 (5 个稳定版本)
1.2.0 | 2022 年 8 月 15 日 |
---|---|
1.1.1 | 2022 年 5 月 29 日 |
1.0.1 | 2021 年 11 月 7 日 |
1.0.0 | 2021 年 10 月 28 日 |
0.1.0 | 2021 年 5 月 28 日 |
#1572 在 编码
每月 85 次下载
31KB
597 行
ActixExtractMultipart
用于更轻松处理 actix 多部分的功能。您可以将多部分转换为结构。
要使用此函数,您需要创建一个具有 "Deserialize" 特性的结构,如下所示
#[derive(Deserialize)]
struct Example {
string_param: String,
optional_u_param: Option<u32>,
files_param: Option<Vec<File>>
}
File 是任何文件的结构
#[derive(Debug, Deserialize)]
pub struct File {
file_type: String,
name: String,
data: FileData,
}
impl File {
pub fn file_type(&self) -> &String {
&self.file_type
}
pub fn name(&self) -> &String {
&self.name
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn data(&self) -> &FileData {
&self.data
}
}
FileData 是 Vec bytes 的别名
pub type FileData = Vec<u8>;
使用示例
use actix_web::{post, App, HttpResponse, HttpServer};
use serde::{Deserialize};
use actix_extract_multipart::*;
#[derive(Deserialize)]
struct Example {
string_param: String,
optional_u_param: Option<u32>,
file_param: File
}
fn saving_file_function(file: &File) -> Result<(), ()> {
// Do some stuff here
println!("Saving file \"{}\" successfully", file.name());
Ok(())
}
#[post("/example")]
async fn index(example_structure: Multipart::<Example>) -> HttpResponse {
println!("Value of string_param: {}", example_structure.string_param);
println!("Value of optional_u_param: {:?}", example_structure.optional_u_param);
println!("Having file? {}", match example_structure.file_param {
Some(_) => "Yes",
None => "No"
});
if let Some(file) = &example_structure.file_param {
match saving_file_function(&file) {
Ok(_) => println!("File saved!"),
Err(_) => println!("An error occured while file saving")
}
}
HttpResponse::Ok().json("Done")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Server run at http://127.0.0.1:8080");
HttpServer::new(move || {
App::new()
.service(index)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
在此示例中,如果您没有收到文件,extract_multipart 将返回 Err(_),因为数据与 "Example" 数据结构不匹配。如果文件是可选的,您可以简单地设置类型为 Option,如下所示
#[derive(Deserialize)]
struct Example {
string_param: String,
optional_u_param: Option<u32>,
file_param: Option<File>
}
对于 Vec,不要忘记在字段名末尾放置挂钩。您还可以使用任何其他类型数组,如 Vec 等。在以下 HTML 示例中,您会注意到文件的字段名包含挂钩:name="files_param[]"。这是非常重要的,如果没有挂钩,此代码将无法工作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Testing</title>
<script>
function send() {
let myHeaders = new Headers();
let formdata = new FormData(document.getElementById('form'));
let myInit = { method: 'POST', headers: myHeaders, body: formdata };
fetch("http://127.0.0.1:8082/example", myInit)
.then(() => {
console.log("It works!")
})
.catch((e) => {
console.log("Error!\n" + e)
})
}
</script>
</head>
<body>
<form id="form">
<input type="file" name="files_param[]" multiple>
<button type="button" onclick="send()">OK</button>
</form>
</body>
</html>
依赖项
~15–26MB
~459K SLoC