最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

rust中間件actix_web在項目中的使用實戰(zhàn)

 更新時間:2024年01月17日 14:31:39   作者:ZHangQL  
這篇文章主要介紹了rust中間件在項目中的使用實戰(zhàn),包括自定義中間件,日志中間件,Default?headers,用戶會話,錯誤處理的用法實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

actix_web 中間件

  • 自定義中間件
  • 日志中間件
  • Default headers
  • 用戶會話
  • 錯誤處理

中間件

中間件介紹 Actix Web 的中間件系統(tǒng)允許我們在請求/響應處理中添加額外的行為。中間件可以與傳入的請求進程掛鉤,使我們能夠秀姑請求以及暫停請求處理以提前返回響應。

中間件可以hook到響應處理,通常中間件涉及一下操作

  • 預處理請求
  • 后處理請求
  • 修改應用狀態(tài)
  • 訪問外部服務(redis、日志、會話)

中間件為每個應用程序、范圍或資源注冊,并以與注冊相反的順序執(zhí)行。一般來說,中間件是一種實現(xiàn) Service 特征和 Transform 特征的類型。每個方法都有一個默認實現(xiàn),每個方法都可以立即返回結(jié)果或返回未來的對象。

自定義中間件

use std::future::{ready, Ready};
use actix_web::{
    dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
    Error,
};
use futures_util::future::LocalBoxFuture;
// There are two steps in middleware processing.
// 1. Middleware initialization, middleware factory gets called with
//    next service in chain as parameter.
// 2. Middleware's call method gets called with normal request.
pub struct SayHi;
// Middleware factory is `Transform` trait
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S, ServiceRequest> for SayHi
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = SayHiMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;
    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(SayHiMiddleware { service }))
    }
}
pub struct SayHiMiddleware<S> {
    service: S,
}
impl<S, B> Service<ServiceRequest> for SayHiMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
    forward_ready!(service);
    fn call(&self, req: ServiceRequest) -> Self::Future {
        println!("Hi from start. You requested: {}", req.path());
        let fut = self.service.call(req);
        Box::pin(async move {
            let res = fut.await?;
            println!("Hi from response");
            Ok(res)
        })
    }
}

對于簡單的用例,可以使用 wrap_fn 來創(chuàng)建笑的,特別的中間件。

use actix_web::{dev::Service as _, web, App};
use futures_util::future::FutureExt;
#[actix_web::main]
async fn main() {
    let app = App::new()
        .wrap_fn(|req, srv| {
            println!("Hi from start. You requested: {}", req.path());
            srv.call(req).map(|res| {
                println!("Hi from response");
                res
            })
        })
        .route(
            "/index.html",
            web::get().to(|| async { "Hello, middleware!" }),
        );
}

日志中間件

日志是作為中間件實現(xiàn)的,通常將日志中間件注冊為應用程序的第一個中間件,必須為每個應用程序注冊日志中間件。

Logger 中間件使用標準日志箱記錄信息,您應該為actix web 包啟用記錄器以表查看訪問日志(env_logger或類似)。

使用指定的格式創(chuàng)建 Logger 中間件。默認記錄器可以用默認方法創(chuàng)建,使用默認的格式。

%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T

例子:

use actix_web::middleware::Logger;
use env_logger::Env;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{App, HttpServer};
    env_logger::init_from_env(Env::default().default_filter_or("info"));
    HttpServer::new(|| {
        App::new()
            .wrap(Logger::default())
            .wrap(Logger::new("%a %{User-Agent}i"))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

日志格式

INFO:actix_web::middleware::logger: 127.0.0.1:59934 [02/Dec/2017:00:21:43 -0800] "GET / HTTP/1.1" 302 0 "-" "curl/7.54.0" 0.000397
INFO:actix_web::middleware::logger: 127.0.0.1:59947 [02/Dec/2017:00:22:40 -0800] "GET /index.html HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 Firefox/57.0" 0.000646

見日志篇章

Default headers

要設置默認的響應頭,我們可以使用 DefaultHeaders 中間件。如果響應頭已經(jīng)包含指定的頭,DefaultHeaders 中間件不會設置頭。

use actix_web::{http::Method, middleware, web, App, HttpResponse, HttpServer};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
            .service(
                web::resource("/test")
                    .route(web::get().to(HttpResponse::Ok))
                    .route(web::method(Method::HEAD).to(HttpResponse::MethodNotAllowed)),
            )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

用戶會話

Actix Web 提供了會話管理的通用解決方案,使用 actix-session 中間件可以使用多種后段類型來存儲會話數(shù)據(jù)。默認實現(xiàn)cookie會話后段,也可以添加其他后段實現(xiàn)。

CookieSession 使用 cookie 作為會話存儲,CookieSessionBackend 創(chuàng)建的會話唄限制為存儲少于4000字節(jié)的數(shù)據(jù),因為 payload 必須適合單個 cookie,如果會話長度超過 4000 字節(jié),會產(chǎn)生服務器內(nèi)部錯誤。

可能具有已簽名或私有的安全策略,每個都有一個各自的 CookieSession 構(gòu)造器。

簽名的 cookie 可以被查看,但不能被客戶端修改,客戶端既不能查看也不能修改私有 cookie。構(gòu)造函數(shù)接受一個鍵作為參數(shù),這是 cookie 會話的私鑰——當這個值被改變,所有會話數(shù)據(jù)都會消失。

通常,您可以創(chuàng)建 SessionStorage 中間件并使用特定的后段實現(xiàn)(如 cookiesession)對其進行初始化,要訪問會話數(shù)據(jù),必須使用會話提取器,這個方法返回一個Session 對象,它允許我們獲取或設置會話數(shù)據(jù)。

1、添加依賴

cargo add actix-session

2、例子代碼

use actix_session::{Session, SessionMiddleware, storage::CookieSessionStore};
use actix_web::{web, App, Error, HttpResponse, HttpServer, cookie::Key};
async fn index(session: Session) -> Result<HttpResponse, Error> {
    // access session data
    if let Some(count) = session.get::<i32>("counter")? {
        session.insert("counter", count + 1)?;
    } else {
        session.insert("counter", 1)?;
    }
    Ok(HttpResponse::Ok().body(format!(
        "Count is {:?}!",
        session.get::<i32>("counter")?.unwrap()
    )))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(
                // create cookie based session middleware
                SessionMiddleware::builder(CookieSessionStore::default(), Key::from(&[0; 64]))
                    .cookie_secure(false)
                    .build()
            )
            .service(web::resource("/").to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

錯誤處理

ErrorHandlers 中間件允許我們?yōu)轫憫峁┳远x處理程序,您可以使用 ErrorHandlers::handler 方法為特定狀態(tài)碼注冊自定義錯誤處理程序。您可以修改現(xiàn)有的響應或創(chuàng)建一個全新的響應。錯誤處理程序可以立即返回響應,也可以返回解析為響應的future。

use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
use actix_web::{
    dev,
    http::{header, StatusCode},
    web, App, HttpResponse, HttpServer, Result,
};
fn add_error_header<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
    res.response_mut().headers_mut().insert(
        header::CONTENT_TYPE,
        header::HeaderValue::from_static("Error"),
    );
    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(
                ErrorHandlers::new()
                    .handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_header),
            )
            .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
use actix_web::{
    dev,
    http::{header},
};
fn add_error_header<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
    res.response_mut().headers_mut().insert(
        header::CONTENT_TYPE,
        header::HeaderValue::from_static("Error"),
    );
    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
}
pub async fn web() {
    HttpServer::new(|| {
        App::new()
            .wrap(
                ErrorHandlers::new()
                    .handler(StatusCode::NOT_FOUND, add_error_header),
            )
            .service(web::resource("/found").route(web::get().to(HttpResponse::NotFound)))
    })
    .bind(("127.0.0.1", 18080))
    .unwrap()
    .run()
    .await
    .unwrap();
}
$ curl -v   --location --request GET  'http://127.0.0.1:18080/a/found'
Note: Unnecessary use of -X or --request, GET is already inferred.
*   Trying 127.0.0.1:18080...
* Connected to 127.0.0.1 (127.0.0.1) port 18080 (#0)
> GET /a/found HTTP/1.1
> Host: 127.0.0.1:18080
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< content-length: 0
< content-type: Error
< date: Fri, 10 Nov 2023 10:01:50 GMT
< 
* Connection #0 to host 127.0.0.1 left intact

以上就是rust 中間件在項目中的使用實戰(zhàn)的詳細內(nèi)容,更多關于rust 中間件的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解Rust Substrate框架中的Runtime

    詳解Rust Substrate框架中的Runtime

    ubstrate是一個區(qū)塊鏈開發(fā)框架,它提供了一系列模塊化和可擴展的組件,可以幫助開發(fā)人員快速構(gòu)建自定義區(qū)塊鏈。 Runtime是Substrate區(qū)塊鏈的核心部分,文中有詳細的代碼示例,需要的朋友可以參考下
    2023-05-05
  • 詳解Rust中的方法

    詳解Rust中的方法

    方法其實就是結(jié)構(gòu)體的成員函數(shù),在C語言中的結(jié)構(gòu)體是沒有成員函數(shù)的,但是Rust畢竟也是一門面向?qū)ο蟮木幊陶Z言,所以給結(jié)構(gòu)體加上方法的特性很符合面向?qū)ο蟮奶攸c,這篇文章主要介紹了Rust中的方法,需要的朋友可以參考下
    2022-10-10
  • 關于Rust?使用?dotenv?來設置環(huán)境變量的問題

    關于Rust?使用?dotenv?來設置環(huán)境變量的問題

    在項目中,我們通常需要設置一些環(huán)境變量,用來保存一些憑證或其它數(shù)據(jù),這時我們可以使用dotenv這個crate,接下來通過本文給大家介紹Rust?使用dotenv來設置環(huán)境變量的問題,感興趣的朋友一起看看吧
    2022-01-01
  • rust多樣化錯誤處理(從零學習)

    rust多樣化錯誤處理(從零學習)

    一個優(yōu)秀的項目,錯誤處理的優(yōu)雅性是至關重要的,而rust,anyhow creat是繞不過去的一個,今天我們來研究下,怎么使用它,幫助我們寫出更優(yōu)雅的代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-11-11
  • Rust語言之Copy和Clone詳解

    Rust語言之Copy和Clone詳解

    在 Rust 中,Copy 和 Clone trait 用于控制類型的復制行為。它們允許你定義如何復制類型的值,以及在什么情況下可以復制。本文將詳細介紹這兩個 trait 的作用和用法,并通過代碼示例來展示它們的使用,需要的朋友可以參考下
    2023-05-05
  • Rust語言中級教程之指針

    Rust語言中級教程之指針

    Rust中共有三種類型的指針,分別為引用,解引用,智能指針,這篇文章主要介紹了Rust語言中級教程之指針,需要的朋友可以參考下
    2023-05-05
  • Rust讀取配置文件的實現(xiàn)

    Rust讀取配置文件的實現(xiàn)

    本文主要介紹了Rust讀取配置文件的實現(xiàn),主要讀取Cargo.toml文件,讀取.env文件和讀取自定義toml文件這三種,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Rust中字符串與格式化操作方法

    Rust中字符串與格式化操作方法

    Rust提供了多種字符串類型和強大的格式化工具,主要有兩種字符串類型:&str(字符串切片)和String(動態(tài)字符串),二者均基于UTF-8 編碼,本文重點介紹Rust中字符串與格式化的相關知識,感興趣的朋友一起看看吧
    2025-10-10
  • Rust中的derive屬性示例詳解

    Rust中的derive屬性示例詳解

    derive屬性的出現(xiàn)解決了手動實現(xiàn)一些特性時需要編寫大量重復代碼的問題,它可以讓編譯器自動生成這些特性的基本實現(xiàn),從而減少了程序員需要編寫的代碼量,這篇文章主要介紹了Rust中的derive屬性詳解,需要的朋友可以參考下
    2023-04-04
  • RUST語言函數(shù)的定義與調(diào)用方法

    RUST語言函數(shù)的定義與調(diào)用方法

    定義一個RUST函數(shù)使用fn關鍵字,下面通過本文給大家介紹RUST語言函數(shù)的定義與調(diào)用方法,感興趣的朋友跟隨小編一起看看吧
    2024-04-04

最新評論

靖安县| 田林县| 泽库县| 凌云县| 桐庐县| 岱山县| 新余市| 鄂托克旗| 诸暨市| 涪陵区| 乌鲁木齐县| 青浦区| 阿图什市| 唐山市| 日土县| 临武县| 辛集市| 铜山县| 稻城县| 绥化市| 长汀县| 区。| 怀远县| 犍为县| 桦川县| 稻城县| 桐乡市| 山东省| 乡宁县| 石家庄市| 烟台市| 同心县| 石林| 太保市| 临泽县| 安西县| 湄潭县| 泌阳县| 邯郸市| 虹口区| 凌源市|