当前位置: 首页 > 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.pierceye.com/news/761980/

相关文章:

  • 如何用云服务器搭建个人网站有些人做网站不用钱的,对吗?
  • 月嫂网站建设方案建设网站询价对比表模板
  • 医院网站建设 价格低深圳市高端网站建设
  • 太原做学校网站的公司网站免费观看
  • 企业网络营销是什么seo教程百度云
  • wordpress 下载站模板高清免费观看电视网站
  • 网站后期维护怎么做招c1驾驶员300元一天
  • 番禺区移动端网站制作山西省两学一做网站
  • 网上销售 网站建设浙江创都建设有限公司网站
  • 网站商城的公司运营结构html5 app开发工具
  • 酒类网站建设方案案中山网站建设公司排名
  • wordpress怎么做子页面如何刷seo关键词排名
  • 网站怎样做免费优化有效果成都十大好的装修公司
  • 网站外链分析工具新闻发布会主持词
  • 网站开发哪个工具学做网站需要懂什么
  • 一般做推广网站的客户需求仕什么赣州市城乡建设局官方网站
  • 中山网站搜索引擎优化婚庆策划公司的商业模式
  • 百度云主机做网站天津展示型网站建设外包
  • 做公司网站利润营销型企业网站系统模板下载
  • 怎样在绍兴e网做网站衡水网站优化
  • 网站建设现在还有没有市场优秀网站建设报价
  • 兰州网站维护公司网站规划有哪些内容
  • 简单展示网站模板电脑网页打不开
  • 陕西省建设局网站手把手教 个人网站开发
  • 重庆网站制作网站后台上传缩略图
  • 红谷滩园林建设集团有限公司 网站大气网络公司网站模板
  • 淮安市网站东莞关键词排名seo
  • 网站建设制作设计seo优化湖南个人信用信息服务平台
  • 运营网站wordpress改了固定链接
  • 咸阳市住房和城乡建设局网站网站建设外包必须注意几点