javaer学rust(八)

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 13,079评论 2 59
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,087评论 19 139
  • 1、什么是MVC 2、什么是SpringMVC 3、SpringMVC的特点 1、开发环境 2、创建maven工程...
    小茅同学阅读 288评论 0 0
  • JSV5 1、vue 双向绑定的原理 通过object.defineProperty()方法来劫持属性的gette...
    merlinxu阅读 1,198评论 0 1
  • 前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了。 当然这只是一个玩...
    编程嘟嘟阅读 816评论 0 1