Responses 响应

Response

类似于构建器的模式用于构造HttpResponse的实例。 HttpResponse提供了几种返回HttpResponseBuilder实例的方法,该实例实现了用于构建responses的各种便捷方法。

检查文档以获取类型说明。

.body, .finish, 和 .json方法完成response创建并返回构造的HttpResponse实例。如果在同一构建器实例上多次调用此方法,则构建器将出现panic。

use actix_web::HttpResponse;

async fn index() -> HttpResponse {
    HttpResponse::Ok()
        .content_type("plain/text")
        .header("X-Hdr", "sample")
        .body("data")
}

Content encoding 内容编码

Actix-web可以使用Compress中间件自动压缩payloads。支持以下编解码器:

  • Brotli
  • Gzip
  • Deflate
  • Identity
use actix_web::{middleware, HttpResponse};

async fn index_br() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

根据来自middleware::BodyEncoding trait的编码参数压缩Response payload。 默认情况下,使用ContentEncoding::Auto。 如果选择ContentEncoding::Auto,则压缩取决于请求的Accept-Encoding header。

ContentEncoding::Identity可用于禁用压缩。 如果选择了其他content encoding,则将对该编码解码器强制执行压缩。

例如,要为单个处理程序启用brotli,请使用ContentEncoding::Br

use actix_web::{http::ContentEncoding, dev::BodyEncoding, HttpResponse};

async fn index_br() -> HttpResponse {
    HttpResponse::Ok()
        .encoding(ContentEncoding::Br)
        .body("data")
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{middleware, web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

或对于整个应用程序:

use actix_web::{http::ContentEncoding, dev::BodyEncoding, HttpResponse};

async fn index_br() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{middleware, web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::new(ContentEncoding::Br))
            .route("/", web::get().to(index_br))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

在这种情况下,我们通过将content encoding设置为Identity值来显式禁用content压缩:

use actix_web::{
    http::ContentEncoding, middleware, dev::BodyEncoding, HttpResponse,
};

async fn index() -> HttpResponse {
    HttpResponse::Ok()
        // v- disable compression
        .encoding(ContentEncoding::Identity)
        .body("data")
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::default())
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

在处理已压缩的body时(例如,在提供assets时),请将content encoding设置为Identity以避免压缩已压缩的数据,并手动设置content-encoding header:

use actix_web::{
    http::ContentEncoding, middleware, dev::BodyEncoding, HttpResponse,
};

static HELLO_WORLD: &[u8] = &[
    0x1f, 0x8b, 0x08, 0x00, 0xa2, 0x30, 0x10, 0x5c, 0x00, 0x03, 0xcb, 0x48, 0xcd, 0xc9,
    0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1, 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf,
    0x0c, 0x00, 0x00, 0x00,
];

async fn index() -> HttpResponse {
    HttpResponse::Ok()
        .encoding(ContentEncoding::Identity)
        .header("content-encoding", "gzip")
        .body(HELLO_WORLD)
}

也可以在应用程序级别设置默认的content encoding,默认情况下使用ContentEncoding::Auto,这意味着自动进行content压缩协商。

use actix_web::{http::ContentEncoding, middleware, HttpResponse};

async fn index() -> HttpResponse {
    HttpResponse::Ok().body("data")
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Compress::new(ContentEncoding::Br))
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8088")?
    .run()
    .await
}

JSON Response

Json类型允许使用格式正确的JSON数据进行响应:只需返回Json<T>类型的值,其中T是要序列化为JSON的结构的类型。类型T必须实现serde的Serialize特性。

use actix_web::{web, HttpResponse, Result};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct MyObj {
    name: String,
}

async fn index(obj: web::Path<MyObj>) -> Result<HttpResponse> {
    Ok(HttpResponse::Ok().json(MyObj {
        name: obj.name.to_string(),
    }))
}

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{App, HttpServer};

    HttpServer::new(|| App::new().route(r"/a/{name}", web::get().to(index)))
        .bind("127.0.0.1:8088")?
        .run()
        .await
}
接下来: 测试