提取器
类型安全的信息提取
Actix提供类型安全请求信息提取功能。默认情况下,actix提供了几个提取器实现。
访问提取器
如何访问Extractor取决于您使用的是处理函数还是自定义Handler类型。
在Handler函数内
提取器可以被传递到一个处理函数作为函数参数 或通过调用ExtractorType::<…>::extract(req)
功能的功能范围内访问。
// Option 1: passed as a parameter to a handler function
fn index((params, info): (Path<(String, String,)>, Json<MyInfo>)) -> HttpResponse {
...
}
// Option 2: accessed by calling extract() on the Extractor
use actix_web::FromRequest;
fn index(req: &HttpRequest) -> HttpResponse {
let params = Path::<(String, String)>::extract(req);
let info = Json::<MyInfo>::extract(req);
...
}
在自定义Handler类型中
与Handler函数一样,自定义Handler类型可以通过调用ExtractorType :: <...> :: extract(&req)
函数来访问 Extractor
。无法将Extractor 作为参数传递给自定义Handler类型,因为自定义Handler类型必须遵循handle实现的Handler
trait指定的函数签名。
struct MyHandler(String);
impl<S> Handler<S> for MyHandler {
type Result = HttpResponse;
/// Handle request
fn handle(&self, req: &HttpRequest<S>) -> Self::Result {
let params = Path::<(String, String)>::extract(req);
let info = Json::<MyInfo>::extract(req);
...
HttpResponse::Ok().into()
}
}
Path
Path提供可从Request的路径中提取的信息。您可以从路径反序列化任何变量段。
例如,对于为/users/{userid}/{friend}
路径注册的资源,可以对两个段进行反序列化,userid以及friend。这些片段可以被提取到一个tuple
,即Path<(u32, String)>
或任何Deserialize
从serde
crate 实现trait的结构中。
use actix_web::{App, Path, Result, http};
/// extract path info from "/users/{userid}/{friend}" url
/// {userid} - - deserializes to a u32
/// {friend} - deserializes to a String
fn index(info: Path<(u32, String)>) -> Result<String> {
Ok(format!("Welcome {}! {}", info.1, info.0))
}
fn main() {
let app = App::new().resource(
"/users/{userid}/{friend}", // <- define path parameters
|r| r.method(http::Method::GET).with(index)); // <- use `with` extractor
}
记得!必须使用Route::with() 方法注册使用提取器的处理函数 。
还可以将路径信息提取到Deserialize
从serde实现特征的特定类型。这是一个使用serde 而不是元组类型的等效示例。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Path, Result, http};
#[derive(Deserialize)]
struct Info {
userid: u32,
friend: String,
}
/// extract path info using serde
fn index(info: Path<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.friend))
}
fn main() {
let app = App::new().resource(
"/users/{userid}/{friend}", // <- define path parameters
|r| r.method(http::Method::GET).with(index)); // <- use `with` extractor
}
Query
可以使用请求的查询完成相同的操作。的查询 类型提供提取功能。在它下面使用serde_urlencoded
箱子。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Query, http};
#[derive(Deserialize)]
struct Info {
username: String,
}
// this handler get called only if the request's query contains `username` field
fn index(info: Query<Info>) -> String {
format!("Welcome {}!", info.username)
}
fn main() {
let app = App::new().resource(
"/index.html",
|r| r.method(http::Method::GET).with(index)); // <- use `with` extractor
}
Json
Json Json允许将请求主体反序列化为结构。要从请求的正文中提取类型信息,该类型T
必须实现 serde的Deserialize
trait。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Json, Result, http};
#[derive(Deserialize)]
struct Info {
username: String,
}
/// deserialize `Info` from request's body
fn index(info: Json<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.username))
}
fn main() {
let app = App::new().resource(
"/index.html",
|r| r.method(http::Method::POST).with(index)); // <- use `with` extractor
}
一些提取器提供了一种配置提取过程的方法。Json提取器 JsonConfig类型用于配置。使用时注册处理程序时Route::with()
,它将返回配置实例。在Json提取器的情况下,它返回一个JsonConfig
。您可以配置json有效内容的最大大小以及自定义错误处理函数。
以下示例将有效负载的大小限制为4kb,并使用自定义错误处理程序。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Json, HttpResponse, Result, http, error};
#[derive(Deserialize)]
struct Info {
username: String,
}
/// deserialize `Info` from request's body, max payload size is 4kb
fn index(info: Json<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.username))
}
fn main() {
let app = App::new().resource(
"/index.html", |r| {
r.method(http::Method::POST)
.with_config(index, |cfg| {
cfg.limit(4096) // <- change json extractor configuration
cfg.error_handler(|err, req| { // <- create custom error response
error::InternalError::from_response(
err, HttpResponse::Conflict().finish()).into()
})
});
});
}
Form
目前只支持url编码的表单。可以将URL编码的主体提取为特定类型。此类型必须实现serde
crate中的Deserialize
特征。
FormConfig允许配置提取过程。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Form, Result};
#[derive(Deserialize)]
struct FormData {
username: String,
}
/// extract form data using serde
/// this handler gets called only if the content type is *x-www-form-urlencoded*
/// and the content of the request could be deserialized to a `FormData` struct
fn index(form: Form<FormData>) -> Result<String> {
Ok(format!("Welcome {}!", form.username))
}
# fn main() {}
多提取器
Actix为元素实现的tuples(最多10个元素)提供了提取器实现FromRequest
。
例如,我们可以同时使用路径提取器和查询提取器。
#[macro_use] extern crate serde_derive;
use actix_web::{App, Query, Path, http};
#[derive(Deserialize)]
struct Info {
username: String,
}
fn index((path, query): (Path<(u32, String)>, Query<Info>)) -> String {
format!("Welcome {}!", query.username)
}
fn main() {
let app = App::new().resource(
"/users/{userid}/{friend}", // <- define path parameters
|r| r.method(http::Method::GET).with(index)); // <- use `with` extractor
}
其他
Actix还提供了其他几种提取器: