国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

上海龍象建設(shè)集團(tuán)公司網(wǎng)站網(wǎng)絡(luò)平臺營銷

上海龍象建設(shè)集團(tuán)公司網(wǎng)站,網(wǎng)絡(luò)平臺營銷,廣東網(wǎng)頁空間代理,上海做網(wǎng)站大的公司本教程筆記來自 楊旭老師的 rust web 全棧教程,鏈接如下: https://www.bilibili.com/video/BV1RP4y1G7KF?p1&vd_source8595fbbf160cc11a0cc07cadacf22951 學(xué)習(xí) Rust Web 需要學(xué)習(xí) rust 的前置知識可以學(xué)習(xí)楊旭老師的另一門教程 https://www.bili…

本教程筆記來自 楊旭老師的 rust web 全棧教程,鏈接如下:

https://www.bilibili.com/video/BV1RP4y1G7KF?p=1&vd_source=8595fbbf160cc11a0cc07cadacf22951

學(xué)習(xí) Rust Web 需要學(xué)習(xí) rust 的前置知識可以學(xué)習(xí)楊旭老師的另一門教程

https://www.bilibili.com/video/BV1hp4y1k7SV/?spm_id_from=333.999.0.0&vd_source=8595fbbf160cc11a0cc07cadacf22951

項目的源代碼可以查看 git:(注意作者使用的是 mysql 數(shù)據(jù)庫而不是原教程的數(shù)據(jù)庫)

https://github.com/aiai0603/rust_web_mysql

在之前的項目中,我們已經(jīng)使用了 rust 編寫了一些具有增刪改查功能的接口并且進(jìn)行測試,但是作為一款完整的應(yīng)用,他還需要將這些數(shù)據(jù)展示到頁面中的功能;在之前的學(xué)習(xí)中,我們已經(jīng)嘗試過將一個html 頁面提供給用戶,但是在實際開發(fā)中,我們肯定希望我們的數(shù)據(jù)可以綁定到頁面中展示給用戶,類似許多語言提供了模板引擎功能,如 jsp、asp 等,rust也有自己的模板引擎 Tera,找不到官網(wǎng)鏈接了,給一個資料鏈接:

http://www.xiyangw.com/post/17560.html

這節(jié)課我們使用 Tera 來完成一個簡單的新增教師和查詢教師的界面:

架構(gòu)搭建

同樣我們新建一個項目,在開始編寫之前我們先添加我們的依賴

[dependencies]
actix-files = "0.6.0-beta.16"
actix-web = "4.0.0-rc.2"
awc = "3.0.0-beta.21"
chrono = { version = "0.4.19", features = ["serde"] }
dotenv = "0.15.0"
# openssl = { version = "0.10.38", features = ["vendored"] }
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
tera = "1.15.0"

之后我們依次新建 errors.rs , handlers.rs , models.rs 和 routers.rs 作為我們的各個功能模塊,我們編寫一個 mod.rs 將各個模塊導(dǎo)出:

pub mod errors;
pub mod handlers;
pub mod routers;
pub mod models;

之后在根目錄下創(chuàng)建一個 static 文件夾存放我們的模板 html 文件和樣式文件等資源,

最后我們在 bin 目錄下新建我們的 svr.rs 文件作為我們的啟動文件,現(xiàn)在完整的架構(gòu)搭建起來了

配置服務(wù)器

對于這個項目,我們將項目的啟動路徑編寫在配置文件中,方便我們隨時改變他,我們在根目錄編寫一個 .env 文件寫上我們的端口:

HOST_PORT = 127.0.0.1:4396

之后我們在 svr.rs 文件編寫我們的服務(wù)器啟動邏輯,我們獲取配置文件的服務(wù)器啟動地址之后,之后我們將 static 文件夾綁定在 tera 中,這樣 static 文件夾下的文件就會被 tera 識別到,之后我們將 tera 傳入整個項目中,我們的項目就可以使用 tera 這個引擎的相關(guān)內(nèi)容了,最后我們在配置文件的編寫的地址啟動我們的項目:

#[path = "../mod.rs"]
mod wa;use actix_web::{web, App, HttpServer};
use dotenv::dotenv;
use routers::app_config;
use std::env;
use wa::{errors,handlers,models,routers};use tera::Tera;#[actix_web::main]
async fn main() -> std::io::Result<()> {dotenv().ok();let host_port = env::var("HOST_PORT").expect("HOST_PORT 沒有在 .env 文件里設(shè)置")HttpServer::new(move || {let tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"),"/static/**/*")).unwrap();App::new().app_data(web::Data::new(tera)).configure(app_config)}).bind(&host_port)?.run().await
}

業(yè)務(wù)邏輯

現(xiàn)在我們的服務(wù)器已經(jīng)能啟動起來了,我們來為他編寫業(yè)務(wù)邏輯:

首先是 models ,我們編寫兩個數(shù)據(jù)結(jié)構(gòu)方便我們查詢和提交老師的數(shù)據(jù):

use serde::{Deserialize, Serialize};#[derive(Deserialize, Serialize, Debug)]
pub struct TeacherRegisterForm {pub name: String,pub imageurl: String,pub profile: String,}#[derive(Deserialize, Serialize, Debug)]
pub struct TeacherResponse {pub id: i32,pub name: String,pub picture_url: String,pub profile: String,}

之后我們編寫 routers 來配置我們的路由,我們直接訪問頁面的時候展示所有老師的信息,而 register 頁面用于注冊老師,注冊信息通過register-post 發(fā)送,而對靜態(tài)文件的請求可以返回正確的靜態(tài)文件 fs::Files::new("/static","./static") 就是將 /static 文件夾下的內(nèi)容作為我們的靜態(tài)資源列表,當(dāng)用戶請求靜態(tài)資源的時候,就從這個位置獲取他們:

use actix_web::web;
use crate::handlers::*;
use actix_files as fs;pub fn app_config(cfg: &mut web::ServiceConfig) {cfg.service(web::scope("").service(fs::Files::new("/static","./static").show_files_listing()).service(web::resource("/").route(web::get().to(get_all_teacher))).service(web::resource("/register").route(web::get().to(show_register_from))).service(web::resource("/register-post").route(web::post().to(handle_register))));
}

模板引擎的使用

現(xiàn)在我們來依次編寫 handlers 里的處理函數(shù)

首先是默認(rèn)路由的展示教師數(shù)據(jù),首先我們使用 awc_client 這個包來調(diào)用我們之前編寫的接口,測試的時候,我們要將之前編寫的完整的增刪改查的接口 api 項目在 3077 端口啟動起來:

pub async fn get_all_teacher(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {let awc_client = awc::Client::default();let res = awc_client.get("http://localhost:3077/teachers/").send().await.unwrap().json::<Vec<TeacherResponse>>().await.unwrap();
}

在獲取數(shù)據(jù)之后我們把它添加到我們的模板里,我們開啟一個 ctx 上下文,在其中插入 teachers 和 errors 兩個數(shù)據(jù),之后我們將 teachers.html 作為我們的模板,把上下文插入到這個模板中,現(xiàn)在這個模板就可以使用這兩個變量了,通過模板引擎選然后會返回將模板的插值語句變?yōu)椴迦霐?shù)據(jù)的網(wǎng)頁代碼,將它封裝返回,用戶就能看到完整的頁面了:

pub async fn get_all_teacher(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {let awc_client = awc::Client::default();let res = awc_client.get("http://localhost:3077/teachers/").send().await.unwrap().json::<Vec<TeacherResponse>>().await.unwrap();let mut ctx = tera::Context::new();ctx.insert("error", "");ctx.insert("teachers", &res);let s = tmpl.render("teachers.html", &ctx).map_err(|_| MyError::TeraError("Template error".to_string()))?;Ok(HttpResponse::Ok().content_type("text/html").body(s))
}

如下是編寫好的模板,因為這個內(nèi)容不是本教程最關(guān)鍵介紹的編寫頁面的方案,所以這里就簡單給出 demo,如果想要了解模板的更多編寫方法可以自行查閱資料:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>Teachers</title></head><body><h1>教師列表</h1><ol>{% for t in teachers %}<li><h5>{{t.name}}</h5><div>{{t.profile}}</div></li>{% endfor %}</ol><div style="margin: 20px;"><a href="/register"> 注冊老師 </a></div></body>
</html>

同樣我們將我們的 register 界面也寫好,因為初始值都是空的,所以我們給與的上下文信息都是空的:

pub async fn show_register_from(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {let mut ctx = tera::Context::new();ctx.insert("error", "");ctx.insert("current_name", "");ctx.insert("current_imageurl", "");ctx.insert("current_profile", "");let s = tmpl.render("register.html", &ctx).map_err(|_| MyError::TeraError("Template error".to_string()))?;Ok(HttpResponse::Ok().content_type("text/html").body(s))
}

這是 register .html 的頁面:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>register</title><link rel="stylesheet" href="/static/css/register.css" /></head><body><h2 class="header">注冊老師</h2><div class="center"><form action="/register-post" method="post"><label for="name">名字</label><br /><input type="text" name="name" id="name" value="{{current_name}}" /><br /><label for="imageurl">頭像</label><br /><inputtype="text"name="imageurl"id="imageurl"value="{{current_imageurl}}"/><br /><label for="profile">簡介</label><br /><inputtype="text"name="profile"id="profile"value="{{current_profile}}"/><br /><label for="error"><p style="color: red">{{error}}</p> </label><br /><button type="submit" id="button1"> 注冊</button></form></div></body>
</html>

最后我們來寫我們的提交數(shù)據(jù)的邏輯:我們在 post 數(shù)據(jù)到 /register-post 作為我們表單的提交方法,在這個方法的處理函數(shù)中,我們添加一個 web::Form<TeacherRegisterForm> 類型的參數(shù)傳遞我們的表單數(shù)據(jù),要注意,如上的 html 模板,表單的每個字段的 name 屬性必須和我們定義的數(shù)據(jù)結(jié)構(gòu)一一對應(yīng):

我們做一個簡單的判定,如果名字 Dave 那么將錯誤寫到注冊頁面中,保持原來的數(shù)據(jù)不變;

否則我們調(diào)用接口將數(shù)據(jù)寫到數(shù)據(jù)庫中,返回回顯新增數(shù)據(jù)的 id;

pub async fn handle_register(tmpl: web::Data<tera::Tera>,params: web::Form<TeacherRegisterForm>,
) -> Result<HttpResponse, Error> {let mut ctx = tera::Context::new();let s;if params.name == "Dave" {ctx.insert("error", "名字已經(jīng)存在");ctx.insert("current_name", &params.name);ctx.insert("current_imageurl", &params.imageurl);ctx.insert("current_profile", &params.profile);s = tmpl.render("register.html", &ctx).map_err(|_| MyError::TeraError("Template error".to_string()))?;} else {let new_teacher = json!({"name":&params.name,"picture_url":&params.imageurl,"profile":&params.profile});let awc_client = awc::Client::default();let res = awc_client.post("http://localhost:3077/teachers/").send_json(&new_teacher).await.unwrap().body().await?;let teacher_response: TeacherResponse = serde_json::from_str(&std::str::from_utf8(&res)?)?;s = format!("成功,id是:{}",teacher_response.id);}Ok(HttpResponse::Ok().content_type("text/html").body(s))
}

錯誤處理

最后我們補上我們的錯誤處理,與上一個項目的錯誤處理邏輯基本上一致,只是多了一個 TeraError 作為我們模板渲染中發(fā)生的錯誤的錯誤類型:

use actix_web::{error, http::StatusCode, HttpResponse, Result};
use serde::Serialize;
use std::fmt;#[derive(Debug, Serialize)]
pub enum MyError {TeraError(String),ActixError(String),#[allow(dead_code)]NotFound(String),
}#[derive(Debug, Serialize)]
pub struct MyErrorResponse {error_message: String,
}impl MyError {fn error_response(&self) -> String {match self {MyError::TeraError(msg) => {println!("Tera error occurred: {:?}", msg);"Database error".into()}MyError::ActixError(msg) => {println!("Server error occurred: {:?}", msg);"Internal server error".into()}MyError::NotFound(msg) => {println!("Not found error occurred: {:?}", msg);msg.into()}}}
}impl error::ResponseError for MyError {fn status_code(&self) -> StatusCode {match self {MyError::TeraError(_msg) | MyError::ActixError(_msg) => StatusCode::INTERNAL_SERVER_ERROR,MyError::NotFound(_msg) => StatusCode::NOT_FOUND,}}fn error_response(&self) -> HttpResponse {HttpResponse::build(self.status_code()).json(MyErrorResponse {error_message: self.error_response(),})}
}impl fmt::Display for MyError {fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {write!(f, "{}", self)}
}impl From<actix_web::error::Error> for MyError {fn from(err: actix_web::error::Error) -> Self {MyError::ActixError(err.to_string())}
}impl From<tera::Error> for MyError {fn from(err: tera::Error) -> Self {MyError::TeraError(err.to_string())}
}

效果演示

編寫完畢后,我們將項目啟動,然后將上一個編寫的增刪改查項目的 demo 在 3077 這個端口啟動,現(xiàn)在我們在網(wǎng)頁輸入 127.0.0.1:4396:

請?zhí)砑訄D片描述

之后我們點擊注冊老師頁面:

請?zhí)砑訄D片描述

我們添加一個新的老師:

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

我們在測試一下 Dave:

請?zhí)砑訄D片描述

最后返回我們的首頁,剛剛注冊的老師顯示出來了:

請?zhí)砑訄D片描述

ok 我們的項目測試成功了,如果你沒有運行成功可以查看這個 git 的 stage8:

https://github.com/aiai0603/rust_web_mysql

http://m.aloenet.com.cn/news/43919.html

相關(guān)文章:

  • wordpress上傳swf網(wǎng)站優(yōu)化排名公司哪家好
  • 鄭州上海做網(wǎng)站的公司有哪些熊貓關(guān)鍵詞工具
  • 張家口手機(jī)臺app下載武漢百度推廣優(yōu)化
  • 公司網(wǎng)站維護(hù)費大概需要多少seo綜合查詢 站長工具
  • 東莞萬江網(wǎng)站制作網(wǎng)絡(luò)營銷產(chǎn)品的特點
  • 如何做網(wǎng)站的需求分析系統(tǒng)清理優(yōu)化工具
  • 閔行區(qū)做網(wǎng)站公司百度指數(shù)工具
  • 我們網(wǎng)站的優(yōu)勢北京seo報價
  • wordpress 獨立站營銷網(wǎng)站建設(shè)規(guī)劃
  • 純css做的響應(yīng)式網(wǎng)站一鍵優(yōu)化
  • 設(shè)計網(wǎng)站什么叫空間不穩(wěn)定seo關(guān)鍵詞排名優(yōu)化銷售
  • 大型購物網(wǎng)站開發(fā)網(wǎng)絡(luò)推廣軟文范文
  • 樂山網(wǎng)站建設(shè)培訓(xùn)學(xué)校網(wǎng)站seo優(yōu)化發(fā)布高質(zhì)量外鏈
  • ps網(wǎng)站設(shè)計怎么做快速收錄網(wǎng)
  • 如何讓人幫忙做網(wǎng)站網(wǎng)站檢測
  • 怎么做跳轉(zhuǎn)流量網(wǎng)站搜索引擎調(diào)詞軟件
  • 怎樣做網(wǎng)頁游戲網(wǎng)站線上推廣是什么意思
  • 網(wǎng)站如何做導(dǎo)航軟文營銷文章案例
  • 免費做頭像網(wǎng)站色盲圖
  • 百度網(wǎng)站是怎么做的營銷案例最新
  • 深圳建站公司專業(yè)公司最近熱點新聞事件2023
  • 焦作企業(yè)網(wǎng)站建設(shè)網(wǎng)站提交
  • 站長工具綜合查詢ip怎樣在百度答題賺錢
  • 羅崗網(wǎng)站建設(shè)手機(jī)網(wǎng)絡(luò)優(yōu)化軟件
  • 做網(wǎng)站專家種子搜索引擎
  • 怎么做微信電影網(wǎng)站nba最新交易匯總
  • wordpress 安全 插件高級seo
  • 網(wǎng)站空間虛擬主機(jī)長沙seo外包服務(wù)
  • 萊特幣做空 網(wǎng)站百度灰色關(guān)鍵詞代發(fā)
  • 上海外貿(mào)seo推廣百度快速seo優(yōu)化