美文网首页
javaer学rust(八)

javaer学rust(八)

作者: yiang飞扬 | 来源:发表于2022-11-11 16:03 被阅读0次

文件上传下载先暂告一段落,接下来我们来开发授权服务。我们选用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)]宏

相关文章

  • javaer学rust(八)

    文件上传下载先暂告一段落,接下来我们来开发授权服务。我们选用actix-web框架进行开发,其它的框架还有rock...

  • javaer学rust(四)

    之前实现了文件上传下载的功能,这次我们利用go-fastdfs实现一个分片上传的功能,按照惯例,先贴代码 这段代码...

  • Javaer学rust(七)

    前面我们实现了一个简陋的线程池,其中线程worker会轮询去线程池的队列里面获取要执行的线程,有就执行,没有就不执...

  • Javaer学rust(六)

    前面我们通过多线程完成了文件分片上传,但如果分片多了,会创建比较多的线程,线程多了切换就会带来比较大的开销,下面我...

  • Javaer学rust(五)

    在前面,我们使用多线程的时候,因为所有权的原因,我们把相关变量都通过clone复制了一遍,这肯定不是好办法,经过查...

  • javaer学rust(一)

    最近研究了下rust,看了些相关资料,很多地方还是半知半解,想着写个demo练练手,正好手头在弄一个文件服务器,便...

  • javaer学rust(二)

    按照之前的规划,我们先实现一个下载文件的功能,在此之前我们先部署一个go-fastdfs服务,go-fastdfs...

  • javaer学rust(三)

    在上一篇,我们写了一个只有main方法的demo,实现了下载网络文件的功能,但基于代码复用的思想,我们可以把下载的...

  • RUST学习资源

    《通过例子学 Rust》 《Rust by Example》 《Rust 程序设计语言(第一版)》 《Rust 程...

  • Rust从安装到语法基础

    rust学习资源 rust中文网[https://www.rust-lang.org/zh-CN/]通过例子学ru...

网友评论

      本文标题:javaer学rust(八)

      本文链接:https://www.haomeiwen.com/subject/urpztdtx.html