请求参数 #

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