javaer学rust(八)

2022-11-11  本文已影响0人  yiang飞扬

文件上传下载先暂告一段落,接下来我们来开发授权服务。我们选用actix-web框架进行开发,其它的框架还有rocket、axum、wrap等,大家可以根据自己的喜好进行选择。只所以选择actix-web,主要发现写法和spring有点像,采用的是分散路由的方式,可以通过宏进行方式进行注解,后来发现还是得进行集中注册,感觉被骗了。言归正传,既选之则用之,先来熟悉下actix-web的用法。

首先创建完工程后,需要在cargo.toml中添加相关的依赖

[dependencies]
actix-web = "4"
actix-multipart="0.4.0"
futures-util="0.3.25"
async-stream="0.3.3"
serde = { version = "1.0", features = ["derive"] }

下面来启动一个web服务器并实现一个基础的服务,访问服务器的时候会返回一个ok,如下:

use actix_web::*;

#[get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("ok")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(||{
        App::new().service(index)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

看起来是不是挺简单的,我们通过rust宏来标记一个路由为'/',请求为get方法的服务,是不是看起来和spring的写法很像,可惜美中不足的是还需要把服务手动注册到HttpServer上,即下面的代码:

 HttpServer::new(||{
        App::new().service(index)
    })

其中index就是上面的index方法,可以写多个,如:

App::new().service(method1)
             .service(method2)
             .service(method3)

熟悉了相关结构,下面再来看下,如何实现相关的表单、queryParam、multipart等参数的接收


use actix_web::{get, post, web, App, HttpServer, Responder, HttpResponse, HttpRequest, FromRequest, HttpMessage};
use actix_web::web::{Form, Bytes, Query, Payload};
use actix_web::dev::{ServiceRequest, AppConfig};
use serde::Deserialize;
use std::collections::HashMap;
use actix_multipart::Multipart;
use futures_util::stream::StreamExt;

// 需要添加serde依赖
#[derive(Deserialize)]
struct TestData {
    name: String,
    value: String
}

#[get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("ok")
}

#[get("/{name}/{value}")]
async fn url_path_param(urlParams: web::Path<TestData>) -> impl Responder {
    let params=urlParams.into_inner();
    println!("{},{}",params.name,params.value);
    HttpResponse::Ok().body("ok")
}

#[get("/queryParam")]
async fn query_param(param:Query<TestData>) -> impl Responder {
    println!("{},{}",param.name,param.value);
    HttpResponse::Ok().body("ok")
}

// query param参数也可以通过通过HashMap接收
#[get("/queryParam2")]
async fn query_param2(queryParams:Query<HashMap<String,String>>) -> impl Responder {
    let params=queryParams.into_inner();
    println!("{:?},{:?}",params.get("name"),params.get("value"));
    HttpResponse::Ok().body("ok")
}


#[get("/{name}/{value}/compose")]
async fn compose(urlParams: web::Path<TestData>,queryParams:Query<TestData>) -> impl Responder {
    let url_params=urlParams.into_inner();
    println!("urlPath:{:?},{:?}",url_params.name,url_params.value);
    println!("query:{:?},{:?}",queryParams.name,queryParams.value);
    HttpResponse::Ok().body("ok")
}

#[post("/formRequest")]
async fn post_form(req :Form<TestData>) -> impl Responder {
    println!("{:?},{}",req.name,req.value);
    HttpResponse::Ok().body("ok")
}

#[post("/bodyRequest")]
async fn body_request(mut payload :Payload) -> impl Responder {
    let body=payload.next().await.unwrap().unwrap().to_vec();
    println!("{:?}",String::from_utf8(body));

    HttpResponse::Ok().body("ok")
}

// 需要添加actix-multipart依赖
#[post("/multipartRequest")]
async fn multipart_request(mut multipart:actix_multipart::Multipart) -> impl Responder {

    while let Some(item) = multipart.next().await {
        let mut field = item.unwrap();
        // Field in turn is stream of *Bytes* object
        while let Some(chunk) = field.next().await {
            println!("-- CHUNK: \n{:?}", std::str::from_utf8(&chunk.unwrap()));
        }
    };
    HttpResponse::Ok().body("ok")
}



#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(move || {
        App::new()
            .service(index)
            .service(url_path_param)
            .service(query_param)
            .service(query_param2)
            .service(compose)
            .service(post_form)
            .service(body_request)
            .service(multipart_request)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

相关代码比较简单,就不一一介绍了,重点说两个
1、如果要使用multipart/form-data这种格式,需要单独添加actix-multipart依赖
2、因为涉及到网络传输和对象转换,请求的接收对象需要添加#[derive(Deserialize)]宏

上一篇 下一篇

猜你喜欢

热点阅读