ActixWeb框架实战案例精萃
使用 Actix Web 框架编写的简易案例
以下是一些使用 Actix Web 框架编写的简易案例示例,涵盖常见功能,每个案例均以独立代码块展示:
基础路由与响应
use actix_web::{get, App, HttpServer, Responder};#[get("/")]
async fn hello() -> impl Responder {"Hello, Actix Web!"
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().service(hello)).bind("127.0.0.1:8080")?.run().await
}
路径参数解析
在Rust中,路径参数通常用于Web框架(如Actix-web、Rocket或Warp)中,用于从URL路径中提取动态值。例如,/users/123
中的123
可以解析为用户的ID。
Actix-web 路径参数解析示例
以下是一个使用Actix-web框架解析路径参数的完整示例:
use actix_web::{get, web, App, HttpServer, Responder};#[get("/users/{user_id}")]
async fn get_user(info: web::Path<(u32,)>) -> impl Responder {format!("User ID: {}", info.0)
}#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().service(get_user)).bind("127.0.0.1:8080")?.run().await
}
说明:
{user_id}
定义路径参数占位符。web::Path<(u32,)>
提取参数并解析为u32
类型。- 访问
/users/123
会返回User ID: 123
。
Rocket 路径参数解析示例
以下是Rocket框架的路径参数解析示例:
#[macro_use] extern crate rocket;#[get("/users/<user_id>")]
fn get_user(user_id: u32) -> String {format!("User ID: {}", user_id)
}#[launch]
fn rocket() -> _ {rocket::build().mount("/", routes![get_user])
}
说明:
<user_id>
定义路径参数占位符。- 参数直接绑定到函数参数
user_id
,类型为u32
。
Warp 路径参数解析示例
以下是Warp框架的路径参数解析示例:
use warp::Filter;#[tokio::main]
async fn main() {let user_route = warp::path!("users" / u32).map(|user_id| format!("User ID: {}", user_id));warp::serve(user_route).run(([127, 0, 0, 1], 8080)).await;
}
说明:
path!("users" / u32)
定义路径参数并直接解析为u32
。- 访问
/users/123
会返回User ID: 123
。
多参数解析示例
以Actix-web为例,解析多个路径参数:
#[get("/users/{user_id}/posts/{post_id}")]
async fn get_post(info: web::Path<(u32, u32)>) -> impl Responder {format!("User ID: {}, Post ID: {}", info.0, info.1)
}
说明:
- 路径
/users/123/posts/456
会提取两个参数,分别赋值给info.0
和info.1
。
自定义类型解析
路径参数支持自定义类型,只需实现FromRequest
(Actix-web)或FromParam
(Rocket)等 trait。以下是一个Rocket的自定义类型示例:
struct UserId(u32);#[rocket::async_trait]
impl<'r> rocket::request::FromParam<'r> for UserId {type Error = std::num::ParseIntError;fn from_param(param: &'r str) -> Result<Self, Self::Error> {param.parse().map(UserId)}
}#[get("/users/<user_id>")]
fn get_user(user_id: UserId) -> String {format!("User ID: {}", user_id.0)
}
说明:
- 自定义类型
UserId
实现FromParam
,允许从路径参数中解析。
以上示例涵盖了Rust中常见框架的路径参数解析方法,可根据项目需求选择合适的实现方式。
Rust JSON请求与响应实例
使用reqwest
库发送JSON请求
确保在Cargo.toml
中添加依赖:
[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
发送POST请求并处理JSON响应:
use serde::{Deserialize, Serialize};
use reqwest::Client;#[derive(Serialize, Deserialize)]
struct Post {title: String,body: String,user_id: u32,
}#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let client = Client::new();let post = Post {title: "Rust JSON Example".to_string(),body: "This is a test post".to_string(),user_id: 1,};let res = client.post("https://jsonplaceholder.typicode.com/posts").json(&post).send().await?;let response_json: Post = res.json().await?;println!("Response: {:?}", response_json);Ok(())
}
处理GET请求的JSON响应
#[derive(Debug, Deserialize)]
struct Todo {userId: u32,id: u32,title: String,completed: bool,
}#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {let res = reqwest::get("https://jsonplaceholder.typicode.com/todos/1").await?.json::<Todo>().await?;println!("Todo: {:?}", res);Ok(())
}
使用serde_json
手动解析JSON
use serde_json::{Value, json};fn parse_json() {let data = r#"{"name": "John Doe","age": 30,"is_active": true}"#;let v: Value = serde_json::from_str(data).unwrap();println!("Name: {}", v["name"]);let json_value = json!({"key": "value","nested": {"number": 42}});println!("Serialized: {}", json_value.to_string());
}
自定义响应错误处理
async fn fetch_data() -> Result<Todo, Box<dyn std::error::Error>> {let resp = reqwest::get("https://jsonplaceholder.typicode.com/todos/1").await?.json::<Todo>().await?;Ok(resp)
}#[tokio::main]
async fn main() {match fetch_data().await {Ok(data) => println!("Success: {:?}", data),Err(e) => println!("Error: {}", e),}
}
添加请求头
use reqwest::header;let client = Client::new();
let res = client.post("https://api.example.com/data").header(header::CONTENT_TYPE, "application/json").header("X-Custom-Header", "Rust").json(&post).send().await?;
以上示例覆盖了Rust中常见的JSON请求与响应场景,包括序列化/反序列化、错误处理和自定义配置。根据实际需求选择合适的HTTP客户端库(如reqwest
或hyper
)和JSON处理方式(如serde_json
)。
use actix_web::{post, web, App, HttpResponse};
use serde::{Deserialize, Serialize};#[derive(Serialize, Deserialize)]
struct User {name: String,age: u8,
}#[post("/user")]
async fn create_user(user: web::Json<User>) -> HttpResponse {HttpResponse::Ok().json(user.into_inner())
}
静态文件服务
使用 warp
框架实现静态文件服务
warp
是一个轻量级异步 Web 框架,适合构建静态文件服务。以下示例展示如何通过 warp
提供 ./static
目录下的文件:
use warp::Filter;#[tokio::main]
async fn main() {let static_files = warp::path("static").and(warp::fs::dir("./static"));warp::serve(static_files).run(([127, 0, 0, 1], 3030)).await;
}
访问 http://localhost:3030/static/文件名
即可获取文件。
使用 actix-web
框架实现静态文件服务
actix-web
是高性能 Web 框架,以下代码配置静态文件服务: