当前位置: 首页 > news >正文

重庆皇华建设集团有限公司网站wordpress 优化

重庆皇华建设集团有限公司网站,wordpress 优化,开封市建设银行网站,eclipse做企业网站文章目录 Actix-web定义中间件(middleware)记录接口耗时中间件简介中间件添加的两种方式#xff08;接口耗时中间件#xff09;使用wrap_fn 闭包实现使用warp struct实现中间件调用顺序actix自带的接口耗时中间件 鉴权中间件 Actix-web定义中间件(middleware)记录接口耗时 … 文章目录 Actix-web定义中间件(middleware)记录接口耗时中间件简介中间件添加的两种方式接口耗时中间件使用wrap_fn 闭包实现使用warp struct实现中间件调用顺序actix自带的接口耗时中间件 鉴权中间件 Actix-web定义中间件(middleware)记录接口耗时 actix-web的官网关于中间件的介绍如下 https://actix.rs/docs/middleware/ 这里使用的是最新版的actix-web旧版本的可能接口不太一样 # actix-web actix-rt 2.6.0 actix-web 4.0.0中间件简介 我们添加的中间件能干什么我们用一段代码来观察一下 下面是官方提供的中间件的定义方式之一我们可以看到闭包里面有两个参数req和srv 其中reqactix_web::dev::ServiceRequest就是请求了你可以通过它来获取请求的各种属性比如请求的路径 req.path()srv 是一个 mut dyn actix_web::dev::Service 类型的参数代表服务处理程序。通过调用 srv.call(req)我们将请求传递给实际的服务处理程序进行处理。这里其实使用的是装饰器模式这使得我们能在具体service方法调用前后做一些操作。官网上写到可以添加这些操作 Pre-process the Request在请求时做前置处理Post-process a Response在响应时进行后置处理Modify application state修改state。state是我actix-web在整个调用链路中的上下文可以用来存储我们自己想要保存的数据Access external services (redis, logging, sessions)可以访问外部的服务例如redis等等 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| {// Pre-process the Requestprintln!(Hi from start. You requested: {}, req.path());srv.call(req).map(|res| {// Post-process a Responseprintln!(Hi from response);res})}).route(/index.html,web::get().to(|| async { Hello, middleware! }),); }中间件添加的两种方式接口耗时中间件 上述添加中间件的方式其实是通过wrap_fn来实现的我们可以通过传入闭包的方式完成我们中间件的逻辑 但是一般我们中间件处理的逻辑可能很多在闭包中修改会显得很冗余我们还可以通过方法warp传入一个实现了 Service trait and Transform trait 的struct这样就会调用我们实现好的方法 在实现前我们需要先添加一些依赖 # actix-web actix-rt 2.6.0 actix-web 4.0.0 # 提供对异步编程的支持和工具 futures-util 0.3使用wrap_fn 闭包实现 use actix_web::{dev::Service as _, web, App}; use futures_util::future::FutureExt; use std::time::{Duration, Instant};#[actix_web::main] async fn main() {let app App::new().wrap_fn(|req, srv| {let start_time Instant::now();let path req.path().to_owned();let fut srv.call(req);async move {let res fut.await;let elapsed_time start_time.elapsed();println!(Request to {} took {:?},path,elapsed_time);res}}).route(/index.html,web::get().to(|| async { Hello, middleware! }),); }这样就能打印接口耗时的日志了 Request to /index.html took 381.325909ms使用warp struct实现 使用struct需要实现两个traitTransform和Service // 中间件 打印接口耗时use std::{future::{ready, Ready}, time::Instant};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. Middlewares call method gets called with normal request. pub struct Timed;// Middleware factory is Transform trait // S - type of the next service // B - type of responses body implS, B TransformS, ServiceRequest for Timed whereS: ServiceServiceRequest, Response ServiceResponseB, Error Error,S::Future: static,B: static, {type Response ServiceResponseB;type Error Error;type InitError ();type Transform TimedMiddlewareS;type Future ReadyResultSelf::Transform, Self::InitError;fn new_transform(self, service: S) - Self::Future {ready(Ok(TimedMiddleware { service }))} }pub struct TimedMiddlewareS {service: S, }implS, B ServiceServiceRequest for TimedMiddlewareS whereS: ServiceServiceRequest, Response ServiceResponseB, Error Error,S::Future: static,B: static, {type Response ServiceResponseB;type Error Error;type Future LocalBoxFuturestatic, ResultSelf::Response, Self::Error;forward_ready!(service);fn call(self, req: ServiceRequest) - Self::Future {let start_time Instant::now();let path req.path().to_owned();let method req.method().to_string();let remote_addr req.connection_info().peer_addr().unwrap_or(unknown).to_string();let version format!({:?}, req.version()); // 使用 format! 宏转换版本号为字符串let headers req.headers().clone();println!({}, 1. Pre-process the Request);let fut self.service.call(req);Box::pin(async move {let res fut.await?;let elapsed start_time.elapsed();let status res.status();let content_length res.headers().get(actix_web::http::header::CONTENT_LENGTH).and_then(|v| v.to_str().ok()).unwrap_or(-);let user_agent headers.get(actix_web::http::header::USER_AGENT).and_then(|v| v.to_str().ok()).unwrap_or(-);println!({}, 2. Post-process a Response)println!({} {} {} {} {} {} {} time took [{:.6}] ms,remote_addr,method,path,version,status.as_u16(),content_length,user_agent,elapsed.as_millis());Ok(res)})} }在主程序中添加 use actix_web::{dev::Service as _, web, App}; use futures_util::future::FutureExt; use std::time::{Duration, Instant};#[actix_web::main] async fn main() {let app App::new().wrap_fn(|req, srv| {println!({}, 2. Pre-process the Request)let start_time Instant::now();let path req.path().to_owned();let fut srv.call(req);async move {let res fut.await;let elapsed_time start_time.elapsed();println!({}, 3. Post-process a Response)println!(Request to {} took {:?},path,elapsed_time);res}}).wrap(Timed).route(/index.html,web::get().to(|| async { Hello, middleware! }),); }打印情况 1. Pre-process the Request 2. Pre-process the Request 3. Post-process a Response Request to /index.html took 70.694224ms 4. Post-process a Response 127.0.0.1 GET /index.html HTTP/1.1 200 - Apifox/1.0.0 (https://www.apifox.cn) time took [70] ms中间件调用顺序 如果我们有多个中间件调用顺序可以从官方上看到这样一句话 Warning: if you use wrap() or wrap_fn() multiple times, the last occurrence will be executed first. 也就是后面添加的中间件会先执行 笔者根据上面添加的中间件对于前置和后置处理我们可以总结出调用顺序 前置比后置处理先调用前置处理是后添加的先执行后置处理按照中间件添加的属性进行执行 actix自带的接口耗时中间件 其实在actix中自带了接口耗时的记录我们只需要指定日志并启用就可以看到了 # 日志相关 log 0.4.0 env_logger 0.10.0use actix_web::{dev::Service as _, web, App, middleware}; use futures_util::future::FutureExt; use std::time::{Duration, Instant}; use log::info;#[actix_web::main] async fn main() {// 初始化日志init_logger();let app App::new()// 日志中间件.wrap(middleware::Logger::default()).wrap_fn(|req, srv| {println!({}, 2. Pre-process the Request)let start_time Instant::now();let path req.path().to_owned();let fut srv.call(req);async move {let res fut.await;let elapsed_time start_time.elapsed();println!({}, 3. Post-process a Response)println!(Request to {} took {:?},path,elapsed_time);res}}).wrap(Timed).route(/index.html,web::get().to(|| async { Hello, middleware! }),); }fn init_logger() {use env_logger::fmt::Color;use env_logger::Env;use log::LevelFilter;let env Env::default().filter_or(MY_LOG_LEVEL, debug);// 设置日志打印格式env_logger::Builder::from_env(env).format(|buf, record| {let level_color match record.level() {log::Level::Error Color::Red,log::Level::Warn Color::Yellow,log::Level::Info Color::Green,log::Level::Debug | log::Level::Trace Color::Cyan,};let mut level_style buf.style();level_style.set_color(level_color).set_bold(true);let mut style buf.style();style.set_color(Color::White).set_dimmed(true);writeln!(buf,{} {} [{}] {},Local::now().format(%Y-%m-%d %H:%M:%S),level_style.value(record.level()),style.value(record.module_path().unwrap_or(unnamed)),record.args())}).filter(None, LevelFilter::Debug).init();info!(env_logger initialized.); }日志打印 2023-08-24 16:06:14 INFO [teacher_service] env_logger initialized. 2023-08-24 16:06:14 INFO [actix_server::builder] starting 2 workers 2023-08-24 16:06:14 INFO [actix_server::server] Actix runtime found; starting in Actix runtime 1. Pre-process the Request 2. Pre-process the Request 2023-08-24 16:06:50 INFO [teacher_service::my_middleware::auth] 2. Hi from start. You requested: /teacher 2023-08-24 16:06:50 INFO [teacher_service] 1. Hi from start. You requested: /teacher 2023-08-24 16:06:50 INFO [teacher_service] 2. Hi from response 2023-08-24 16:06:50 INFO [teacher_service::my_middleware::auth] 1. Hi from response 3. Post-process a Response Request to /teacher took 355.839222ms 4. Post-process a Response 2023-08-24 16:06:50 INFO [teacher_service::my_middleware::timedMiddleware] 127.0.0.1 GET /teacher HTTP/1.1 200 - Apifox/1.0.0 (https://www.apifox.cn) time took [355] ms 2023-08-24 16:06:50 INFO [actix_web::middleware::logger] 127.0.0.1 GET /teacher HTTP/1.1 200 191 - Apifox/1.0.0 (https://www.apifox.cn) 0.355607最后一行就是actix日志记录请求的调用情况最后一个参数就是调用时间单位是秒 鉴权中间件 我们用相同的思路写一个鉴权的中间件这里具体的校验规则读者可以实现一下 use std::future::{ready, Ready};use actix_web::{dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},error,http::header::HeaderValue,middleware::ErrorHandlerResponse,Error, HttpResponse, }; use futures_util::{future::{self, LocalBoxFuture},FutureExt, }; use log::info;// There are two steps in middleware processing. // 1. Middleware initialization, middleware factory gets called with // next service in chain as parameter. // 2. Middlewares call method gets called with normal request. pub struct Auth;// Middleware factory is Transform trait // S - type of the next service // B - type of responses body implS, B TransformS, ServiceRequest for Auth whereS: ServiceServiceRequest, Response ServiceResponseB, Error Error,S::Future: static,B: static, {type Response ServiceResponseB;type Error Error;type InitError ();type Transform AuthMiddlewareS;type Future ReadyResultSelf::Transform, Self::InitError;fn new_transform(self, service: S) - Self::Future {ready(Ok(AuthMiddleware { service }))} }pub struct AuthMiddlewareS {service: S, }implS, B ServiceServiceRequest for AuthMiddlewareS whereS: ServiceServiceRequest, Response ServiceResponseB, Error Error,S::Future: static,B: static, {type Response ServiceResponseB;type Error Error;type Future LocalBoxFuturestatic, ResultSelf::Response, Self::Error;forward_ready!(service);fn call(self, req: ServiceRequest) - Self::Future {// 进行鉴权操作判断是否有权限if has_permission(req) {// 有权限继续执行后续中间件let fut self.service.call(req);Box::pin(async move {let res fut.await?;Ok(res)})} else {// 没有权限立即返回响应Box::pin(async move {// 鉴权失败返回未授权的响应停止后续中间件的调用Err(error::ErrorUnauthorized(Unauthorized))})}} }fn has_permission(req: ServiceRequest) - bool {// 实现你的鉴权逻辑根据需求判断是否有权限// 返回 true 表示有权限返回 false 表示没有权限// unimplemented!()let value HeaderValue::from_str().unwrap();let token req.headers().get(token).unwrap_or(value);token.len() 0 || req.path().to_string() /login }接下来我们在启动的App上加上中间件这里我们要注意⚠️如果我们有很多中间件我们肯定是想要我们的鉴权中间件先执行的这样如果鉴权没有过就不执行后面中间件的逻辑 根据官方的提示后添加的中间件会先执行。我们应该把鉴权中间件放到最后面的位置 use actix_web::{dev::Service as _, web, App, middleware}; use futures_util::future::FutureExt; use std::time::{Duration, Instant}; use log::info;#[actix_web::main] async fn main() {// 初始化日志init_logger();let app App::new()// 日志中间件.wrap(middleware::Logger::default()).wrap_fn(|req, srv| {println!({}, 2. Pre-process the Request)let start_time Instant::now();let path req.path().to_owned();let fut srv.call(req);async move {let res fut.await;let elapsed_time start_time.elapsed();println!({}, 3. Post-process a Response)println!(Request to {} took {:?},path,elapsed_time);res}}).wrap(Timed)// 添加自己中间件的路径.wrap(my_middleware::auth::Auth).route(/index.html,web::get().to(|| async { Hello, middleware! }),); }fn init_logger() {use env_logger::fmt::Color;use env_logger::Env;use log::LevelFilter;let env Env::default().filter_or(MY_LOG_LEVEL, debug);// 设置日志打印格式env_logger::Builder::from_env(env).format(|buf, record| {let level_color match record.level() {log::Level::Error Color::Red,log::Level::Warn Color::Yellow,log::Level::Info Color::Green,log::Level::Debug | log::Level::Trace Color::Cyan,};let mut level_style buf.style();level_style.set_color(level_color).set_bold(true);let mut style buf.style();style.set_color(Color::White).set_dimmed(true);writeln!(buf,{} {} [{}] {},Local::now().format(%Y-%m-%d %H:%M:%S),level_style.value(record.level()),style.value(record.module_path().unwrap_or(unnamed)),record.args())}).filter(None, LevelFilter::Debug).init();info!(env_logger initialized.); }这样当我们鉴权失败后后续的中间件就不会执行了下面笔者写了一个接口 鉴权成功 日志也符合预期
http://www.zqtcl.cn/news/761980/

相关文章:

  • html5可以做交互网站吗打开网站说建设中是什么问题?
  • 彩票网站开发制作需要什么wordpress 在线预览
  • 外贸平台app衡水seo排名
  • 怎样做网站表白墙东莞商城网站推广建设
  • 郑州郑州网站建设河南做网站公司哪家好爱站长尾词挖掘工具
  • dede网站地图文章变量网站qq 微信分享怎么做
  • 越南做网站网站建设以及运营方面
  • 广西建网站哪家好网站关闭与域名备案
  • 网站开发版本号婚庆网站建设策划案费用预算
  • 厦门建设网站制作中山市哪家公司做网站
  • 网站路径wordpress制作电商网站
  • 江西网站开发哪家专业装饰设计公司网站
  • 企业网站策划实训Wordpress 主题简化
  • 做网站点击挣钱不兰州工程建设信息网站
  • 网站说服力 营销...免费看片网站
  • 深圳招聘网站大全制作网站软件下载
  • 网站建设说明哈尔滨网站建设渠道
  • 一 网站建设管理基本情况设计类的网站
  • wordpress产品编辑如何优化wordpress
  • 网站后台更新缓存失败网站平台规划方案
  • 网站开发需求分析主要内容saas建站系统是怎么实现的
  • 做qq头像的网站有哪些wordpress怎么部署到虚拟linux服务器
  • 征求网站建设企业网站建设word
  • 市民服务中心网站建设小型公众号开发
  • 服装网站建设策划书论文基层建设刊物网站
  • 网站建设合同技术开发合同范本wordpress备份和还原
  • 物流信息平台网站建设一流本科专业建设点网站
  • 天猫网站建设的目标是什么装潢设计软件
  • 电商网站首页图片网站功能模块建设
  • 邮件服务器是不是网站服务器黄江网站建设公司