请求参数 #
Rocket提供了多种方式来获取和处理请求参数,包括路径参数、查询参数、请求头等。本节将详细介绍这些参数的处理方法。
参数类型概览 #
| 参数类型 | 来源 | 语法 |
|---|---|---|
| 路径参数 | URL路径 | <param> |
| 查询参数 | URL查询字符串 | ?<param> |
| 表单数据 | 请求体 | data = "<form>" |
| JSON数据 | 请求体 | data = "<json>" |
| 请求头 | HTTP头部 | FromRequest |
路径参数 #
基本用法 #
rust
#[get("/user/<id>")]
fn get_user(id: u32) -> String {
format!("User ID: {}", id)
}
多个路径参数 #
rust
#[get("/user/<user_id>/post/<post_id>")]
fn get_post(user_id: u32, post_id: u32) -> String {
format!("User {}'s post {}", user_id, post_id)
}
路径参数类型 #
rust
#[get("/int/<num>")]
fn int_param(num: i32) -> String {
format!("Integer: {}", num)
}
#[get("/float/<num>")]
fn float_param(num: f64) -> String {
format!("Float: {}", num)
}
#[get("/bool/<val>")]
fn bool_param(val: bool) -> String {
format!("Boolean: {}", val)
}
#[get("/string/<s>")]
fn string_param(s: String) -> String {
format!("String: {}", s)
}
多段路径 #
rust
use std::path::PathBuf;
#[get("/files/<path..>")]
fn get_files(path: PathBuf) -> String {
format!("Path: {:?}", path)
}
查询参数 #
单个查询参数 #
rust
#[get("/search?<q>")]
fn search(q: &str) -> String {
format!("Searching: {}", q)
}
多个查询参数 #
rust
#[get("/search?<q>&<page>&<limit>")]
fn search_paginated(q: &str, page: u32, limit: u32) -> String {
format!("Searching '{}' - Page {} (limit: {})", q, page, limit)
}
可选查询参数 #
rust
#[get("/items?<category>&<sort>")]
fn list_items(category: Option<&str>, sort: Option<&str>) -> String {
let cat = category.unwrap_or("all");
let order = sort.unwrap_or("date");
format!("Category: {}, Sort by: {}", cat, order)
}
结构化查询参数 #
rust
use rocket::request::Query;
use rocket::FromForm;
#[derive(FromForm)]
struct SearchParams {
q: String,
page: Option<usize>,
per_page: Option<usize>,
sort: Option<String>,
}
#[get("/search?<params..>")]
fn search(params: Query<SearchParams>) -> String {
let page = params.page.unwrap_or(1);
let per_page = params.per_page.unwrap_or(10);
format!("Search '{}' - Page {} ({} items)", params.q, page, per_page)
}
数组查询参数 #
rust
#[derive(FromForm)]
struct FilterParams {
#[field(name = "tag")]
tags: Vec<String>,
#[field(name = "category")]
categories: Vec<String>,
}
#[get("/filter?<params..>")]
fn filter(params: Query<FilterParams>) -> String {
format!("Tags: {:?}, Categories: {:?}", params.tags, params.categories)
}
访问:/filter?tag=rust&tag=web&category=backend&category=framework
请求头 #
获取单个请求头 #
rust
use rocket::http::Header;
#[get("/header")]
fn get_header(header: &Header<'_>) -> String {
format!("{}: {}", header.name(), header.value())
}
获取特定请求头 #
rust
use rocket::request::Request;
#[get("/user-agent")]
fn user_agent(request: &Request<'_>) -> String {
let ua = request.headers()
.get_one("User-Agent")
.unwrap_or("Unknown");
format!("User-Agent: {}", ua)
}
使用FromRequest获取请求头 #
rust
use rocket::request::{self, FromRequest, Request, Outcome};
use rocket::http::Status;
struct ApiKey(String);
#[rocket::async_trait]
impl<'r> FromRequest<'r> for ApiKey {
type Error = ();
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match request.headers().get_one("X-API-Key") {
Some(key) => Outcome::Success(ApiKey(key.to_string())),
None => Outcome::Error((Status::Unauthorized, ())),
}
}
}
#[get("/protected")]
fn protected(api_key: ApiKey) -> String {
format!("API Key: {}", api_key.0)
}
Content-Type处理 #
检查内容类型 #
rust
use rocket::http::ContentType;
#[post("/upload", data = "<data>")]
fn upload(data: Vec<u8>, content_type: &ContentType) -> String {
format!("Received {} bytes of {}", data.len(), content_type)
}
根据内容类型路由 #
rust
#[post("/data", format = "json", data = "<data>", rank = 1)]
fn json_data(data: Json<Data>) -> String {
format!("JSON: {:?}", data)
}
#[post("/data", format = "form", data = "<data>", rank = 2)]
fn form_data(data: Form<Data>) -> String {
format!("Form: {:?}", data)
}
Cookie处理 #
读取Cookie #
rust
use rocket::http::CookieJar;
#[get("/cookie")]
fn get_cookie(jar: &CookieJar<'_>) -> String {
match jar.get("session") {
Some(cookie) => format!("Session: {}", cookie.value()),
None => "No session cookie".to_string(),
}
}
设置Cookie #
rust
use rocket::http::{Cookie, SameSite};
#[get("/set-cookie")]
fn set_cookie(jar: &CookieJar<'_>) -> &'static str {
jar.add(Cookie::build(("session", "abc123"))
.http_only(true)
.secure(true)
.same_site(SameSite::Lax)
.finish());
"Cookie set"
}
删除Cookie #
rust
#[get("/logout")]
fn logout(jar: &CookieJar<'_>) -> &'static str {
jar.remove("session");
"Logged out"
}
完整示例 #
rust
#[macro_use] extern crate rocket;
use rocket::request::Query;
use rocket::FromForm;
use rocket::http::CookieJar;
use rocket::serde::json::Json;
#[derive(FromForm)]
struct Pagination {
#[field(default = 1)]
page: usize,
#[field(default = 10)]
per_page: usize,
}
#[derive(rocket::serde::Serialize, rocket::serde::Deserialize)]
#[serde(crate = "rocket::serde")]
struct User {
id: u32,
name: String,
email: String,
}
#[get("/")]
fn index() -> &'static str {
"API Root"
}
#[get("/users/<id>")]
fn get_user(id: u32) -> Json<User> {
Json(User {
id,
name: "Alice".to_string(),
email: "alice@example.com".to_string(),
})
}
#[get("/users?<pagination..>")]
fn list_users(pagination: Query<Pagination>) -> String {
format!("Page {} with {} users", pagination.page, pagination.per_page)
}
#[get("/session")]
fn get_session(jar: &CookieJar<'_>) -> String {
match jar.get("user_id") {
Some(cookie) => format!("User ID: {}", cookie.value()),
None => "Not logged in".to_string(),
}
}
#[get("/login/<user_id>")]
fn login(user_id: u32, jar: &CookieJar<'_>) -> String {
use rocket::http::Cookie;
jar.add(Cookie::new("user_id", user_id.to_string()));
format!("Logged in as user {}", user_id)
}
#[launch]
fn rocket() -> _ {
rocket::build()
.mount("/api", routes![
index,
get_user,
list_users,
get_session,
login
])
}
测试示例 #
bash
# 获取用户
curl http://127.0.0.1:8000/api/users/1
# 分页列表
curl "http://127.0.0.1:8000/api/users?page=2&per_page=20"
# 登录
curl http://127.0.0.1:8000/api/login/123
# 获取会话
curl -b "user_id=123" http://127.0.0.1:8000/api/session
下一步 #
掌握了请求参数后,让我们继续学习 表单数据,了解如何处理表单提交。
最后更新:2026-03-28