rust的actix web框架试试手(json数据传输和接受,数据库操作,rust后端操作)

文章目录


##Actix Web(RUST)
###代码
main.rs




    
    Title
    
    


姓名 card_id gender class age

stu.rs

use mysql as my;
use serde_derive::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Eq, Deserialize,Serialize)]
pub struct student_info {
    pub name: String,
    pub card_id: String,
    pub gender: String,
    pub class: i32,
    pub age: i32,
}

impl student_info {
    pub fn new(name: String, card_id: String, gender: String, class: i32, age: i32) -> student_info {
        student_info {
            name: name,
            card_id: card_id,
            gender: gender,
            class: class,
            age: age
        }
    }
}
impl student_info {
    pub fn copy(sp:&student_info) -> student_info {
        student_info {
            name: sp.name.clone(),
            card_id: sp.card_id.clone(),
            gender: sp.gender.clone(),
            class: sp.class.clone(),
            age: sp.age.clone()
        }
    }
}
pub fn stu_select()->Vec{
    let pool = my::Pool::new("mysql://root:123456@localhost:3306/studentinfo").unwrap();

    let mut selected_payments:Vec =
        pool.prep_exec("SELECT  *  from stuinfo limit 1", ())
            .map(|result|
                {
                    result.map(|x| x.unwrap()).map(|row|{
                        let (name, card_id, gender,class,age) = my::from_row(row);
                        student_info {
                            name: name,
                            card_id: card_id,
                            gender: gender,
                            class:class,
                            age:age
                    }
                    }).collect()
                }
            ).unwrap();
    selected_payments
}

pub fn stu_insert(v: student_info) {
    let pool = my::Pool::new("mysql://root:123456@localhost:3306/studentinfo").unwrap();
    for mut stmt in pool.prepare(r"INSERT INTO stuinfo
                                       (stuname, card_id, gender,class,age)
                                   VALUES
                                       (:name, :card_id, :gender,:class,:age)").into_iter() {

        stmt.execute(params! {
                "name" => &v.name,
                "card_id" => &v.card_id,
                "gender" => &v.gender,
                "class" => &v.class,
                "age" => &v.age,
            }).unwrap();
    }
}

###解释部分
####后端启动器

 HttpServer::new(|| App::new()
        .data(AppState {
            foo: "bar".to_string(),
        })
        .service(stream)
        .default_service(web::resource("").route(web::get().to(p404)))
        .service(fs::Files::new("/static", "static").show_files_listing())
        .service(inlex)
        .service(web::resource("/form").route(web::get().to(index2)))
        .service(web::resource("/post1").route(web::post().to(handle_post_1)))
        .service(web::resource("/post2").route(web::post().to(handle_post_2)))
        .service(web::resource("/app").route(web::post().to(hand_app)))
        .service(web::resource("/post3").route(web::post().to(handle_post_3)))
        .service(web::resource("/rp").route(web::post().to(replay)))
//        .service(web::resource("/tx").route(web::post().to(index)))

        )
        .bind("127.0.0.1:8088")
        .unwrap()
        .run()
        .unwrap();

可以看的出来这个代码部分的结构很明确,就是app。service(映射地址)路由到函数部分。(当然这个有贼多个方式表示,自此不一一列举)
然后可以看到绑定端口,然后在跑起来。
#####函数部分
1.返回json到ajax

fn replay(req:HttpRequest,item: web::Json)->Result>{

    let p=stu::stu_select();
    println!("{:#?}",p);
    println!("{:#?}",req);
    Ok(Json(stu::student_info::copy(&p[0])))
}

可以看到这里的参数有2个一个是json一个是req,req没有用我只是单纯想看看输出数据的。
他的返回是一个结果集以json的方式返回,
这里stu_select是数据库提取器。

2.表单类型

fn handle_post_1(params: web::Form) -> Result {

    Ok(HttpResponse::Ok()
        .content_type("text/plain")
        .body(format!("Your name is {}", params.name)))
}

可以看出其实结构都差不多,就是参数的类型不同,这个其实就是一个form表单的类型了。

3.静态文件直接访问

ttpServer::new(|| App::new()
        .data(AppState {
            foo: "bar".to_string(),
        })
        .service(stream)
        .default_service(web::resource("").route(web::get().to(p404)))
        .service(fs::Files::new("/static", "static").show_files_listing())
        ...//省略掉run的部分

这里创建了一个static的文件夹,里面放的静态文件,这样就可以直接访问这个文件夹的文件了。

4.如何返回一个HTML页面

#[get("/welcome")]
fn stream(req: HttpRequest) -> Result{
    Ok(HttpResponse::build(StatusCode::OK)
        .content_type("text/html; charset=utf-8")
        .body(include_str!("../static/index.html")))
}

这里可以直接使用#[get("/url)]来直接寻址,或者你也可以用之前的方法效果是一样的。
他的写法也有些不同,是.service(stream)就行了,就个人习惯而言。等会说说可能碰到的错误。
####前端部分
Ajax接受和返回参数
1.前端接受参数

 $("#re").click(function () {
                alert(true)
                $.ajax({
                    type: "POST",
                    url: 'http://127.0.0.1:8088/rp',
                    async: false, // 使用同步方式
                    // 1 需要使用JSON.stringify 否则格式为 a=2&b=3&now=14...
                    // 2 需要强制类型转换,否则格式为 {"a":"2","b":"3"}
                    data: JSON.stringify({
                            name:"name"
                    }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {
                       $("#name").val(data.name),
                            $("#card_id").val(data.card_id),
                            $("#gender").val(data.gender),
                           $("#class").val(data.class),
                           $("#age").val(data.age)
                    } ,// 注意不要在此行增加逗号
                    error: function() {
                       alert("失败")
                    }

                });
                return false
            })

因为才看的Ajax,不知道发生的时候,是否可以不带那个data部分,就随便搞了一个,如果大家有更好的办法,可以分享下,感激不尽
他这到了rust的函数部分后

fn replay(req:HttpRequest,item: web::Json)->Result>{

    let p=stu::stu_select();
    println!("{:#?}",p);
    println!("{:#?}",req);
    Ok(Json(stu::student_info::copy(&p[0])))
}

可以看的出来这里啥也没写,就是一个提取和一个返回。
2.前端发送参数部分

          $("#btn").click(function() {
                alert(true)
                $.ajax({
                    type: "POST",
                    url: 'http://127.0.0.1:8088/app',
                    async:true, // 使用同步方式
                    // 1 需要使用JSON.stringify 否则格式为 a=2&b=3&now=14...
                    // 2 需要强制类型转换,否则格式为 {"a":"2","b":"3"}
                    data: JSON.stringify({
                        name: $("#name").val(),
                        card_id: $("#card_id").val(),
                        gender: $("#gender").val(),
                        class: parseInt($("#class").val()),
                        age: parseInt($("#age").val())
                    }),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {
                        $('#result').text(data.result);
                    } // 注意不要在此行增加逗号
                });
                return false
            })

这个地方就比较容易了,前端只用传输数据,
到了后端的

fn hand_app(req:HttpRequest,item: web::Json)->Result{
    println!("{:#?}",req);
    stu::stu_insert(item.0);
    Ok(HttpResponse::build(StatusCode::OK)
        .content_type("text/html; charset=utf-8")
        .body(include_str!("../static/tx/index.html")))
}
//其实这个返回一点用也没有。。。没出问题我就没管了。
//这里的stu_insert是一个添加函数,这个可以去前面的stu.rs看下怎么弄的,如果有需要怎么搞数据库这边的可以给我留言。

###错误
1.get

The attribute `get` is currently unknown to the compiler and may have meaning added to it in the future

这个错误是因为没有引入get

use actix_web::{get,post};

只需要引入这个包就行了
2.

the trait bound `for<'de> MyParams: _IMPL_DESERIALIZE_FOR_plic::_serde::Deserialize<'de>` is not satisfied

这个类型的错误都有一个特点,就是看
MyParams: _IMPL_DESERIALIZE_FOR_plic::_serde::这个之后的那个内容是什么,缺这个就要补上这个

//首先引入这个
use serde_derive::{Deserialize, Serialize};
//这个往往是在结构体的前面的
#[derive(Deserialize)]
pub struct MyParams {
    name: String,
}
help: consider removing the borrow: `p[0]`

这是一个很常见的错误。
我现在也没有很好的解决方案,只能用clone,
所以碰到结构体除了这个问题,我也就一个一个的参数去clone

impl student_info {
    pub fn copy(sp:&student_info) -> student_info {
        student_info {
            name: sp.name.clone(),
            card_id: sp.card_id.clone(),
            gender: sp.gender.clone(),
            class: sp.class.clone(),
            age: sp.age.clone()
        }
    }
}

类似于这个样子,其实这个主要是因为数据库的返回有点问题才引入这个函数。

你可能感兴趣的:(rust)