Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 我可以从Actix Web中间件获取响应正文并修改它吗?_Rust_Actix Web - Fatal编程技术网

Rust 我可以从Actix Web中间件获取响应正文并修改它吗?

Rust 我可以从Actix Web中间件获取响应正文并修改它吗?,rust,actix-web,Rust,Actix Web,我正在用rust和actixwebframwork开发一个应用程序,我在应用程序中插入了一些中间件实例 我计划中间件将修改响应的正文并在call()方法中返回响应,但我找不到解决方案。我找不到允许从servicesponse获取文本并对其进行修改的示例代码 你们能帮我写一些示例代码来获取响应的正文并修改它吗 下面是我使用的示例代码。我在“sample.rs”的SayHiMiddleware->call()中添加了一条注释,以告知我想要什么 //样品 use actix_service::{Ser

我正在用
rust
actixweb
framwork开发一个应用程序,我在应用程序中插入了一些中间件实例

我计划中间件将修改响应的正文并在call()方法中返回响应,但我找不到解决方案。我找不到允许从
servicesponse
获取文本并对其进行修改的示例代码

你们能帮我写一些示例代码来获取响应的正文并修改它吗

下面是我使用的示例代码。我在“sample.rs”的
SayHiMiddleware->call()
中添加了一条注释,以告知我想要什么

//样品

use actix_service::{Service, Transform};
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
use futures::future::{ok, FutureResult};
use futures::{Future, Poll};

// 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 from actix-service crate
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S> for SayHi
where
    S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = SayHiMiddleware<S>;
    type Future = FutureResult<Self::Transform, Self::InitError>;

    fn new_transform(&self, service: S) -> Self::Future {
        ok(SayHiMiddleware { service })
    }
}

pub struct SayHiMiddleware<S> {
    service: S,
}

impl<S, B> Service for SayHiMiddleware<S>
where
    S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;

    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
        self.service.poll_ready()
    }

    fn call(&mut self, req: ServiceRequest) -> Self::Future {
        println!("Hi from start. You requested: {}", req.path());

        Box::new(self.service.call(req).and_then(|res| {
            // I want to get response body text and print the text.
            // But I couldnt get the text from ServiceResponse instance..... help me guys T.T
            // And is there way to combine with previous response body text and new text?????
            // example (res->body->text is "aaaaa")) and I want to append new text to the string ( "aaaaa" + "bbbbb" )
            println!("Hi from response");
            Ok(res)
        }))
    }
}
使用actix_服务::{service,Transform};
使用actix_web::{dev::ServiceRequest,dev::ServiceResponse,Error};
使用futures::future:{ok,FutureResult};
使用期货:{Future,Poll};
//中间件处理分为两个步骤。
// 1. 中间件初始化,使用调用中间件工厂
//链中的下一个服务作为参数。
// 2. 中间件的调用方法通过普通请求被调用。
酒馆结构;
//中间件工厂是actix服务机箱的“转换”特性
//`S`-下一个服务的类型
//`B`-响应的主体类型
SayHi的impl变换
哪里
S:服务,
未来:“静态,
B:静态,
{
类型请求=服务请求;
类型响应=服务响应;
类型错误=错误;
类型InitError=();
类型转换=SayHiMiddleware;
类型未来=未来结果;
fn新的_转换(&self,service:S)->self::未来{
ok(SayHiMiddleware{service})
}
}
SayHiMiddleware酒店结构{
服务:S,,
}
SayHiMiddleware的impl服务
哪里
S:服务,
未来:“静态,
B:静态,
{
类型请求=服务请求;
类型响应=服务响应;
类型错误=错误;
输入Future=Box;
fn poll_ready(&mut self)->poll{
self.service.poll_ready()
}
fn调用(&mut self,req:ServiceRequest)->self::Future{
println!(“Hi from start.You requested:{}”,req.path());
框::新建(自助服务)呼叫(req)。然后(| res |{
//我想获取响应正文文本并打印文本。
//但是我无法从ServiceResponse实例中获取文本…帮我伙计们T.T
//有没有办法将之前的回复正文和新正文结合起来?????
//示例(res->body->text为“aaaaa”),我想将新文本附加到字符串(“aaaaa”+“bbbbb”)
println!(“来自回复的Hi”);
好(res)
}))
}
}
//梅因

use actix_web::{web, App, HttpServer};
use actix_service::Service;
use futures::future::Future;

#[allow(dead_code)]
mod redirect;
#[allow(dead_code)]
mod read_request_body;
#[allow(dead_code)]
mod read_response_body;
#[allow(dead_code)]
mod simple;

fn main() -> std::io::Result<()> {
    std::env::set_var("RUST_LOG", "actix_web=debug");
    env_logger::init();

    HttpServer::new(|| {
        App::new()
            .wrap(redirect::CheckLogin)
            .wrap(read_request_body::Logging)
            .wrap(read_response_body::Logging)
            .wrap(simple::SayHi)
            .wrap_fn(|req, srv| {
                println!("Hi from start. You requested: {}", req.path());

                srv.call(req).map(|res| {
                    println!("Hi from response");
                    res
                })
            })
            .service(web::resource("/login").to(|| {
                "You are on /login. Go to src/redirect.rs to change this behavior."
            }))
            .service(
                web::resource("/").to(|| {
                    "Hello, middleware! Check the console where the server is run."
                }),
            )
    })
    .bind("127.0.0.1:8080")?
    .run()
}
使用actix_web::{web,App,HttpServer};
使用actix_service::service;
使用futures::future::future;
#[允许(死代码)]
mod重定向;
#[允许(死代码)]
mod read\u request\u body;
#[允许(死代码)]
mod read_response_body;
#[允许(死代码)]
mod simple;
fn main()->std::io::Result{
std::env::set_var(“RUST_LOG”,“actix_web=debug”);
环境记录器::init();
HttpServer::新建(|||){
App::new()
.wrap(重定向::检查登录)
.wrap(读取请求体::日志记录)
.wrap(读取\响应\正文::日志记录)
.wrap(简单::SayHi)
.wrap|fn(|要求,srv|{
println!(“Hi from start.You requested:{}”,req.path());
srv.call(请求)映射(| res |{
println!(“来自回复的Hi”);
物件
})
})
.service(web::resource(“/login”).to(| |{
“您在/login上。请转到src/redirect.rs以更改此行为。”
}))
.服务(
web::resource(“/”)到(|||){
您好,中间件!请检查运行服务器的控制台
}),
)
})
.bind(“127.0.0.1:8080”)?
.run()
}

谢谢你…

这就是我的工作。我认为可能有更好的方法,但例子不多

///从'input'中提取T类型的响应体`
///例如:
/// 
///让结果:MyResponseBodyContract=TestContext::map_body(&mut resp);
pub异步fn映射体(输入:&mut servicesponse)->T
其中T:反序列化
{
让mut body=input.take_body();
让mut bytes=BytesMut::new();
而让一些(项目)=body.next().等待{
bytes.extend_from_slice(&item.unwrap());
}
let result:T=serde_json::from_slice(&bytes)
.unwrap_或_else(| | panic!(“反序列化期间映射体失败”);
返回结果;
}
我的好友@stephaneyfx帮我把它重构成更好的东西

#[async_trait(?Send)]
发布特性解析响应{
///从'input'中提取T类型的响应正文`
///例如:
/// 
///let result:MyContractType=resp.parse().wait.unwrap();
异步fn解析(&mut self)->结果;
}
#[异步(发送)]
ServiceResponse的impl ParseResponse{
异步fn解析(&mut self)->结果
哪里
T:反序列化拥有,
{
让bytes=self.take_body().try_fold(Vec::new(),| mut acc,chunk | async{
acc.extend(块);
Ok(acc)
});
好(serde_json::from_slice(&bytes.await?)
}
}

这就是我的工作。我认为可能有更好的方法,但例子不多

///从'input'中提取T类型的响应体`
///例如:
/// 
///让结果:MyResponseBodyContract=TestContext::map_body(&mut resp);
pub异步fn映射体(输入:&mut servicesponse)->T
其中T:反序列化
{
让mut body=input.take_body();
让mut bytes=BytesMut::new();
而让一些(项目)=body.next().等待{
bytes.extend_from_slice(&item.unwrap());
}
let result:T=serde_json::from_slice(&bytes)
.打开包装或其他(|