beego:從入門到放棄

使用beego創建新項目

beego 的項目基本都是通過 bee 命令來創建的,所以在創建項目之前確保你已經安裝了 bee 工具和 beego。如果你還沒有安裝,那麼請查閱 beego 的安裝 和 bee 工具的安裝


現在一切就緒我們就可以開始創建項目了,打開終端,進入 $GOPATH/src 所在的目錄:


創建一個項目名爲20180118_loongc_beego的基於beego 的新項目,執行如下命令:

bee new 20180118_loongc_beego


依次執行如下命令:進入目錄,運行該項目,在localhost:8080裏查看,如下圖

cd 20180118_loongc_beego

bee run




配置postgresql 數據庫連接

安裝beego orm, 降低複雜的ORM(Object-Relational Mapping,對象關係映射)學習曲線,執行如下命令:

go get github.com/astaxie/beego


安裝postgresql數據庫驅動,執行如下命令:

go get github.com/lib/pq


在main.go文件裏添加如下代碼:

func init(){

orm.RegisterDriver(“postgres”. orm.DRPostgres)

orm.RegisterDataBase(“default”, “postgres”, “user=postgres password=nasadmin dbname=20180111_loongc_test host=127.0.0.1 port=5432 sslmode=disable”)

orm.RegisterModel(

new(models.User))

orm.RunSyncdb("default", false, true)

}

orm.RegisterDriver爲配置postgresql數據庫驅動

orm.RegisterDataBase中:

“default”是默認項

“postgres”表示使用的是postgresql數據庫

user=postgres password=nasadmin dbname=20180111_loongc_test:分別表示數據庫用戶名、用戶密碼、數據庫名

host=127.0.0.1 port=5432:分別表示數據庫主機地址、數據庫端口(5432是postgresql的默認端口)

orm.RegisterModel:表示註冊model,每添加一個model文件,都需要register,否則無法訪問。當前表示有兩個model,User和Topic

模型構造

在文件夾models下新建文件User.go,文件內容如下:

package models


import (

“github.com/astaxie/beego/orm”

)


type User struct {

Id int `json: “id”`

Username string `json:”username”`

Password string `json:”password”`

Role string `json:”role”`

}

模型User構造完成,一個完整的模型還需要添加函數通用方法,這裏實現一個用戶登錄,在文件中添加用戶登錄驗證函數,如下:

func Login(username string, password string)(bool, User){

o := orm.NewOrm()

var user User

err := o.QueryTable(user).Filter(“Username”, username).Filter(“Password”, password).One(&user)

return err != orm.ErrNoRows, user

}


登錄界面

在views目錄底下添加login.tpl文件,tpl文件是模板寫法,本質還是遵循html文件寫法,但是支持框架本身的很多變量。文件內容如下:

<!DOCTYPE html>

<html>

<head>

<title>Login page</title>

</head>

<body >

<form id="loginform">

id:<input type="text" name="username" value="{{.Username}}"><br>

pw:<input type="password" name="password" value="{{.Password}}"><br>

<input type="button" value="submit" id="loginbtn">

</form>

<script type="text/javascript" src="/static/js/jquery-3.2.1.js"></script>

<script type="text/javascript">

$(function(){

$('#loginbtn').bind('click', function(){

$.ajax({

url: "/login",

type: "post",

asyns: true,

data: $('#loginform').serialize(),

// dataType: "json",

success: function(res){

console.log(res);

if(res){

window.location.href = "/index";

}else{

window.location.href = "/";

}

// console.log({{.flash.success}});

// {{if .flash.success}}

// window.location.href = {{.flash.success}};

// {{end}}

},

error: function(XMLHttpRequest, testStatus, errorThrown){

console.log(XMLHttpRequest.status);

console.log(XMLHttpRequest.readyState);

console.log(testStatus);

}

});

})

});

</script>

</body>

</html>

控制器

beego框架中,所有視圖view顯示,都是要定義在控制器裏的。當登錄頁面已經構建好,但是無法在瀏覽器裏馬上渲染。這也是beego的侷限性,當我需要創建一個新的tpl文件放到服務器端,然後在iframe裏通過src引用的時候,新的tpl的名字是動態的,無法動態的在控制器裏添加定義。

在當前登錄功能中,包括兩個控制器,代碼如下:

一個登錄頁面渲染控制器Loginpage,它定義了模板文件的位置,並且定義了兩個輸入框的值,在登錄頁面通過{{.Username}}的方法給用戶id輸入框設置默認值。

一個登錄驗證控制器Login,它是將用戶提交的username和password拿到之後,然後調用之前model裏定義的方法,實現驗證。驗證成功之後進入index.tpl頁面(主頁),驗證失敗仍停留在login.tpl。這裏仍存在一個beego的問題,如果使用jquery 的ajax方法,beego無法設置返回值,這裏原來的Redirect的也會失效,甚至c.TplName方法也同樣不起作用。

package controllers


import (

"github.com/astaxie/beego"

"server/20180118_loongc_beego/models"

)


type LoginController struct {

beego.Controller

}


func (c *LoginController) Loginpage() {

c.Data["Username"] = "loongc"

c.Data["Password"] = "123"

c.Data["Error"] = ""

c.TplName = "login.tpl"

}


func (c *LoginController) Login() {

flash := beego.NewFlash()

username, password := c.Input().Get("username"), c.Input().Get("password")

if flag, _ := models.Login(username, password); flag {

// c.SetSecureCookie(beego.AppConfig.String("cookie.secure"), beego.AppConfig.String("cookie.role"), user.Role, 1*1*20*60, beego.AppConfig.String("cookie.domain"), "/", false, true)

c.Redirect("/index", 302)

// c.TplName = "index.tpl"

return

} else {

flash.Error("username or password error")

c.Redirect("/error", 302)

return

}

}

路由

登錄界面使用jquery ajax發送的請求是如何被beego框架捕獲的,因爲很明顯的是在這個案例中url給的value是 /login ,這是一個不符合一般化的ajax格式的值,這個是由beego框架自己定義的路由來控制的。在routers目錄底下有一個router.go文件,在這裏定義了前端的所有請求的最後會被分發到不同控制器,代碼如下所示:

package routers


import (

"github.com/astaxie/beego"

"server/20180118_loongc_beego/controllers"

)


func init() {

beego.Router("/", &controllers.LoginController{}, "GET:Loginpage")

beego.Router("/login", &controllers.LoginController{}, "POST:Login")


beego.Router("/index", &controllers.IndexController{}, "GET:Indexpage")

beego.Router("/error", &controllers.IndexController{}, "GET:Error")

}

這裏一共定義了四個四個不同的路由,按順序,分別是初始化web的默認打開頁面、登錄驗證控制器、初始化index.tpl(這個是登錄成功之後打開的頁面),最後一個是在本實例中設計的登錄頁面跳轉問題,後續章節繼續說明。

beego的侷限性和解決登錄跳轉問題
  • 前面已經提到的,對於所有view文件的渲染,都需要事先在控制器裏定義好,對於新生成的view文件,目前來看好像無能爲力
  • 其次,在於與jquery ajax的配合,beego在這種情況下好像無法返回值,當我在控制器裏添加return 一個bool值,並沒有拿到,但是通過控制器裏存在Redirect方法,console.log(res)時,可以返回Redirect的頁面代碼。基於以上,ajax無法獲得控制頁面跳轉的參數,不僅如此,beego自身的頁面跳轉也會出現失效問題。儘管官方提供了擴展方法,但是好像不是很成熟


解決登錄跳轉

在這裏還是堅持ajax做數據發送,因爲並不是所有的情況的都是通過input、testxarea、select輸入要保存的數據。

在這裏提供鑑於console.log(res)出的是要打開頁面的代碼,那麼假設驗證登錄失敗,如果打開的頁面是個空的文檔,那麼if(res) 只有在驗證正確的時候纔會恆爲true,否則就爲false,所以我在路由中定義了一個 /error 的路由,在控制器裏讓它打開一個名爲error.tpl的空文檔,當驗證錯誤的時候console.log(res)是空的,所以if(res)爲false,以此來控制登錄驗證成功與否時的跳轉。但是提示錯誤信息並沒有很好展現

結論

beego是比較完善的框架,但是適用範圍僅限於,按照模板輸出不同數據。

後臺控制跳轉,算不得友好,尤其是前端<a>標籤都無法單獨控制頁面跳轉。

無法實現靈活的數據數據輸入,路由限制決定了數據發送方式被限定太死,不符合實際。尤其是與ajax這種很成熟的數據路由配合都很差。

輸入數據的合法性校驗,由後端完成,這種工作應該儘量由前端完成。









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章