|版權聲明:本文爲博主原創文章,未經博主允許不得轉載。博客地址:https://blog.csdn.net/sgsgy5
小Demo講解
我們今天以註冊和登陸作爲我們今天的demo講解,把前面講到的內容都串起來。先註冊,然後登陸。
在開始具體的業務之前我們要做數據庫設計,在正式開發中這一步是非常重要,也比較複雜的,但是今天我們只實現登陸和註冊,就簡單有個用戶名和密碼即可,model.go內容如下:
package models
import (
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
type User struct {
Id int
Name string
Passwd string
}
func init(){
//1.連接數據庫
orm.RegisterDataBase("default","mysql","root:123456@tcp(127.0.0.1:3306)/test?charset=utf8")
//2.註冊表
orm.RegisterModel(new(User))
//3.生成表
//1.數據庫別名
//2.是否強制更新
//3.創建表過程是否可見
orm.RunSyncdb("default",false,true)
}
註冊
確定註冊請求路徑,修改路由文件
我們這裏以/register
作爲註冊的請求路徑。所以這裏我們需要修改router.go文件的內容。
在router.go文件的init()函數中加下面這行代碼:
beego.Router("/register", &controllers.UserController{},"get:ShowRegister")
根據上面路由的指定,我們需要添加註冊控制器
在controllers文件夾下創建一個user.go,然後在這個文件裏面定義一個結構體UserController
當控制器。
type UserController struct{
beego.Controller
}
注意這裏面添加的
beego.Controller
,是爲了繼承自beego自帶的控制器。
添加顯示註冊頁面函數
添加函數的時候需要注意,這個函數必須是UserController
的函數纔可以,不然在路由裏面調用不到。那如何把函數設置成UserController
的成員函數呢?是在函數名前面加上括號,然後放上UserController
的指針。這裏我們先指定註冊的視圖。代碼如下:
func (this*UserController)ShowRegister(){
this.TplName = "register.html"
}
注意:這裏如果函數名首字母小寫,路由同意找不到函數,所以函數名首字母必須大寫
添加視圖頁面
在views文件夾下面創建一個名字爲register.html
的文件。然後實現成類似界面:
我們做後臺的不關注樣式,下次直接拿現成的樣式來用即可,我們重在實現功能。
form標籤裏面需要添加兩個屬性,一個是action,一個是method,action其實就是請求路徑,這裏處理的還是註冊業務,所以我們還用register請求,action = “/register”,因爲是上傳數據,所以我們把method設置爲post,即method="post"
,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>註冊頁面</title>
</head>
<body>
<div style="position:absolute;left:50%; top:50%;">
<form action="/register" method="post">
用戶名:<input type="text" name="userName">
<p> </p>
密碼:<input type="password" name="passwd">
<p> </p>
<input type="submit" value="註冊">
</form>
</div>
</body>
</html>
讓項目運行起來,然後我們在瀏覽器裏面輸入相應的地址就能看見我們的註冊頁面了。
顯示完註冊頁面之後,接着我們來處理註冊的post請求。因爲action="/register",method=“post”,所以我們可以去router.go界面給post請求指定相應的方法。修改如下:
beego.Router("/register", &controllers.UserController{},"get:ShowRegister;post:HandleRegister")
指定方法名之後我們就需要去控制器中實現他。
註冊業務處理
-
首先在user.go中添加這個函數:
func (this*UserController)HandleRegister(){ }
-
接着開始處理註冊業務
-
首先要獲取數據。這裏給大家介紹一類方法,這類方法將會在我們項目一中高頻率的出現,因爲他的作用太強大了。
this.GetString():獲取字符串類型值
this.GetInt():獲取整型值
this.GetFloat:獲取浮點型值
…
this.GetFile():獲取上傳的文件
作用:接收前端傳遞過來的數據,不管是get請求還是post請求,都能接收。
參數: 是傳遞數據的key值,一般情況下是form表單中標籤的name屬性值返回值:根據返回類型不同,返回值也不一樣,最常用的GetString()只有一個返回值,如果沒有取到值就返回空字符串,其他幾個函數會返回一個錯誤類型。獲取的值一般是標籤裏面的value屬性值。至於比較特殊的,我們用到的時候給大家做介紹。
知道了獲取數據函數,我們就可以獲取前端傳遞過來的數據啦。
-
獲取註冊的用戶名和密碼
userName := this.GetString("userName") passwd := this.GetString("passwd")
-
對數據進行校驗
一般情況下,我們做服務器開發,從前端拿過來數據都要進行一系列的校驗,然後纔會用數據對數據庫進行操作。不做校驗的服務器很容易被黑掉。這裏我們只做簡單的判空校驗。
if userName == "" || passwd == ""{ beego.Info("數據數據不完整,請重新輸入!") this.TplName = "register.html" return }
思考:如何把那句錯誤提示傳遞給視圖?
-
把數據插入數據庫
如果數據校驗沒有問題,那我們就需要把數據插入到數據庫中。數據庫插入操作前面剛講過,這裏就不一步一步的分開介紹了,代碼如下:
//獲取orm對象 o := orm.NewOrm() //獲取要插入的數據對象 var user models.User //給對象賦值 user.Name = userName user.Passwd = passwd //把數據插入到數據庫 if _,err := o.Insert(&user);err != nil{ beego.Info("註冊失敗,請更換用戶名再次註冊!") this.TplName = "register.html" return }
因爲我們現在還沒有其他界面,如果跳轉成功就返回一句話
註冊成功
,等我們實現了登陸界面之後再實現註冊之後跳轉登陸界面的操作。給瀏覽器返回一句化的代碼如下:
this.Ctx.WriteString("註冊成功!")
-
-
完整後臺代碼如下
//顯示註冊頁面 func(this*UserController)ShowRegister(){ this.TplName = "register.html" } //處理註冊業務 func(this*UserController)HandleRegister(){ //獲取前端傳遞的數據 userName := this.GetString("userName") passwd := this.GetString("passwd") //對數據進行校驗 if userName == "" || passwd == ""{ beego.Info("數據數據不完整,請重新輸入!") this.TplName = "register.html" return } //把數據插入到數據庫 //獲取orm對象 o := orm.NewOrm() //獲取要插入的數據對象 var user models.User //給對象賦值 user.Name = userName user.Passwd = passwd //把數據插入到數據庫 if _,err := o.Insert(&user);err != nil{ beego.Info("註冊失敗,請更換用戶名再次註冊!") this.TplName = "register.html" return } //返回提示信息 this.Ctx.WriteString("註冊成功!") }
登陸
登陸和註冊業務流程差不多,差別也就體現在一個是對數據的查詢一個是數據的插入,講義裏面就不做詳細分析,直接貼代碼。
路由文件修改
添加下面一行代碼:
beego.Router("/login", &controllers.UserController{},"get:ShowLogin;post:HandleLogin")
後臺代碼修改
在控制器中添加展示登錄頁的函數ShowLogin
和處理登陸數據的函數HandleLogin
。完整代碼如下:
//顯示登陸界面
func(this*UserController)ShowLogin(){
this.TplName = "login.html"
}
//處理登陸業務
func(this*UserController)HandleLogin(){
//獲取前端傳遞的數據
userName := this.GetString("userName")
passwd := this.GetString("passwd")
//對數據進行校驗
if userName == "" || passwd == ""{
beego.Info("數據數據不完整,請重新輸入!")
this.TplName = "login.html"
return
}
//查詢數據庫,判斷用戶名和密碼是否正確
//獲取orm對象
o := orm.NewOrm()
//獲取要插入的數據對象
var user models.User
//給對象賦值
user.Name = userName
//根據用戶名查詢
if err := o.Read(&user,"Name");err != nil{
beego.Info("用戶名錯誤,請重新輸入!")
this.TplName = "login.html"
return
}
if user.Passwd != passwd{
beego.Info("密碼錯誤,請重新輸入!")
this.TplName = "login.html"
return
}
//返回提示信息
this.Ctx.WriteString("登陸成功!")
}
添加視圖文件
登陸界面和註冊界面很相似,拷貝過來簡單修改一下即可,代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陸頁面</title>
</head>
<body>
<div style="position:absolute;left:50%; top:50%;">
<form action="/login" method="post">
用戶名:<input type="text" name="userName">
<p> </p>
密碼:<input type="password" name="passwd">
<p> </p>
<input type="submit" value="登陸">
</form>
</div>
</body>
</html>
這樣我們的登陸和註冊就算完成了,但是有一個問題,我們的登陸註冊還是各幹各的,沒有關聯起來,我們前面等登陸頁面實現完之後,註冊成功就跳轉到登陸頁面。現在我們來實現一下跳轉。
頁面之間的跳轉
beego裏面頁面跳轉的方式有兩種,一種是重定向,一種是渲染,都能夠在瀏覽器上顯示新的頁面
重定向
重定向用到的方法是 this.Redirect() 函數,有兩個參數,第一個參數是請求路徑,第二個參數是http狀態碼。
請求路徑就不說了,就是和超鏈接一樣的路徑。
我們重點介紹一下狀態碼:
狀態碼一共分爲五類:
1xx : 服務端已經接收到了客戶端請求,客戶端應當繼續發送請求 。常見的請求:100
2xx :請求已成功 (已實現)常見的請求:200
3xx :請求的資源轉換路徑了,請求被跳轉。常見的請求:300,302
4xx :客戶端請求失敗。常見的請求:404
5xx :服務器端錯誤。常見的請求:500
狀態碼詳解:http://tool.oschina.net/commons?type=5
重定向的工作流程是:
1:當服務端向客戶端響應 redirect後,並沒有提供任何view數據進行渲染,僅僅是告訴瀏覽器響應爲 redirect,以及重定向的目標地址
2:瀏覽器收到服務端 redirect 過來的響應,會再次發起一個 http 請求
3:由於是瀏覽器再次發起了一個新的 http 請求,所以瀏覽器地址欄中的 url 會發生變化
4:瀏覽中最終得到的頁面是最後這個 重定向的url 請求後的頁面
5:所以redirect("/register",302) 相當於你在瀏覽器中手動輸入 localhost/register
渲染
渲染就是控制期把一些數據傳遞給視圖,然後視圖用這些輸出組織成html界面。所以不會再給瀏覽器發請求,是服務器自己的行爲,所以瀏覽器的地址欄不會改變,但是顯示的頁面可能會發生變化。用的函數是:this.TplName = "login.html"
兩者之間的區別
區別 | 重定向 | 渲染 |
---|---|---|
響應方式 | 告訴瀏覽器相應是redirect,然後返回一個新的地址給瀏覽器,讓瀏覽器重新發起請求 | 直接給瀏覽器返回視圖 |
地址欄顯示 | 瀏覽器地址欄顯示的是新的地址 | 瀏覽器地址欄顯示的還是原來的地址 |
作用 | 不能給視圖傳遞數據,但是能夠獲取到加載頁面時的數據 | 能夠給視圖傳遞數據,但如果要獲取加載頁面時的數據,需要再次寫相關代碼 |
使用場景 | 頁面跳轉的時候 | 頁面加載或者是登陸註冊失敗的時候 |