編程基礎 0003_Web_beego開發

Web 開發之 Beego

使用 go get 安裝 bee 工具與 beego

使用 bee 工具初始化 Beego 項目

  • $GOPATH/src 目錄下執行 bee create myapp

使用 bee 工具熱編譯 Beego 項目

  • $GOPATH/src/myapp 目錄下執行 bee start myapp
// hello world
package main

import (
    "github.com/astaxie/beego"
)
type HomeController struct {
    beego.Controller
}
// 注意Get首字母大寫。要不會報method not allow
func (this *HomeController) Get() {
    this.Ctx.WriteString("Hello World")
}
func main() {
    beego.Router("/",&HomeController)
    beego.Run()
}

go http

三個包 io/log/net/http

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/",sayHello)
    err:=http.ListenAndServe(":8080",nil)
    if err!=nil {
        log.Fatal(err)
    }
}
func sayHello(w http.ResponseWriter,r *http.Request) {
   io.WriteString(w,"Hello world,this is is version 1.")
}

ListenAdnServe第二個參數添加 handler

package main

import (
    "io"
    "log"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.Handle("/", &myHandler{})
    mux.HandleFunc("/hello",SayHelloV2) //處理func
    err := http.ListenAndServe("0.0.0.0:8080", mux)

    if err!=nil {
        log.Fatal(err)
    }
}

type myHandler struct{}

func (*myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "URL:"+r.URL.String())
}
// 同樣mux也可以HandleFunc

func SayHelloV2(w http.ResponseWriter,r *http.Request)  {
    io.WriteString(w,"Hello world, this is version No.2.")
}

更底層的寫處理 HttpServer

package main

import (
    "io"
    "log"
    "net/http"
    "time"
)
//手動處理路由,在handler中只有一個ServerHTTP

var mx map[string]func(w http.ResponseWriter,r *http.Request)

func main()  {
    server:=http.Server{
        Addr:":8080",
        Handler: &myHandler1{},
        ReadHeaderTimeout:5*time.Second,
    }
    //路由註冊
    mx = make(map[string]func(w http.ResponseWriter,r *http.Request))
    mx["/hello"] =sayHello
    mx["/saybye"] = sayBye
    err:=server.ListenAndServe()
    if err!=nil {
        log.Fatal(err)
    }
}

type myHandler1 struct{}

func (*myHandler1) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    //io.WriteString(w, "URL:"+r.URL.String())
    //這裡來做路由轉發
    if h,ok:=mx[r.URL.String()];ok{
        h(w,r)
        return
    }

    io.WriteString(w, "妹找到-->URL:"+r.URL.String())
}

func sayHello (w http.ResponseWriter, r *http.Request)  {
    io.WriteString(w,"Hello world, this is version no 3")
}

func sayBye(w http.ResponseWriter, r *http.Request)  {
    io.WriteString(w,"Bye bye, this is version no 3")
}

對於 mux 的擴展靜態服務

func main() {
    mux := http.NewServeMux()
    mux.Handle("/", &myHandler{})
    mux.HandleFunc("/hello", SayHelloV2)
    //創建靜態服務
    wd, err := os.Getwd()
    if err != nil {
        log.Fatal(err)
    }
    mux.Handle("/static/",
        http.StripPrefix("/static/", http.FileServer(http.Dir(wd))))
    err = http.ListenAndServe("0.0.0.0:8080", mux)
    if err != nil {
        log.Fatal(err)
    }
}

bee 命令的使用

文檔

  • 新建一個 web 項目 bee new myproject
  • 通過 api 命令可是用來創建 api 應用 bee api apiproject,其目錄結構中我們可以看出少了 static 和 views 目錄,多了一個 test 模塊,用來做單元測試
  • bee run命令是監控 beego 的項目,通過 fsnotify 監控文件系統。但是注意該命令必須在$GOPATH/src/appname下執行
  • bee pack pack 目錄用來發佈應用的時候打包,會把項目打包成 zip 包,這樣我們部署的時候直接把打包之後的項目上傳,解壓就可以部署了
  • bee version 查看 bee beego 和 go 的版本
  • bee generate 命令,用來自動化生成代碼的,包含了從數據庫一鍵生成 model,還包含了 scaffold

beego 配置管理

conf/app.conf 怎麼獲取呢?

package controllers

import (
    "strconv"
    "github.com/astaxie/beego"
)

type MainController struct {
    beego.Controller
}

func (c *MainController) Get() {
    // c.Data["Website"] = "beego.me"
    // c.Data["Email"] = "astaxie@gmail.com"
    // c.TplName = "index.tpl"
    c.Ctx.WriteString("appName:"+beego.AppConfig.String("appname")+
    "\nhttpport"+beego.AppConfig.String("httpport")+
    "\nrunmode"+beego.Appconfig.String("runmode"))
    // 系統默認參數方式 貌似不帶這種方式了
   /*  hp:=strcovItoa(beego.HttpPort)
    c.Ctx.WriteString("appName:"+beego.AppName+
    "\nhttpport"+hp+
    "\nrunmode"+beego.RunMode) */

    //    日誌 及日誌級別
    /*
    LevelEmergency = iota // 緊急級別
        LevelAlert                   // 報警級別
        LevelCritical                // 嚴重錯誤級別
        LevelError                   // 錯誤級別
        LevelWarning              // 警告級別
        LevelNotice                 // 注意級別
        LevelInformational       // 報告級別
        LevelDebug                 // 除錯級別
    */
    log:=logs.NewLogger(10000)
    log.SetLevel(logs.LevelDebug)

}

模板

package controllers

import (
    "strconv"
    "github.com/astaxie/beego"
)

type MainController struct {
    beego.Controller
}

func (c *MainController) Get() {
    c.Data["name"] = "name"
    // 模板中的條件判斷
    c.Data["TrueCond"] = true
    c.Data["FalseCond"] = false
    // 打印一個結構
    type u struct{
        Name string
        age int
        Sex string
    }
    user:=&u{
        Name:"Joe",
        Age:20,
        Sex:"Male"
    }
    c.Data["User"] = user
    // 循環輸出
    nums:=[]int{1,2,3,4,5,6,7,8,9,0}
    c.Data["Nums"] = nums
    // 給模板變量賦值
    c.Data["TplVar"] = "hey  guys"
    // 內置模板函數的功能
    c.Data["Html"] = "<div>Hello Beego</div>"
    c.Data["Pipe"] = "<div>Hello Beego</div>"
}
<!-- tpl -->
<div>
  <!-- 條件判斷 判斷值只能是True 或 false不能用表達式 -->
  {{if .TrueCond}} true condition content {{end}}
</div>
<div>
  <!-- 條件判斷 判斷值只能是True 或 false不能用表達式 -->
  {{if .FalseCond}} {{else}} false condition content {{end}}
</div>
<div>
  <!-- 結構顯示 -->
  {{.User.Name}} {{.User.Age}} {{.User.Sex}}
  <!-- 嵌套輸出 -->
  {{with .User}} {{.Name}} {{.Age}} {{.Sex}} {{end}}
</div>
<div>
  <!-- 單數組 只輸入一個.就可以了 -->
  {{range .Nums}} {{.}} {{end}}
  <!-- 如果是對象的話,因為兼顧了with功能,所以只寫對象屬性就可以了`.屬性名` -->
</div>
<div>
  <!-- 模板變量使用$定義 -->
  {{$tplVar = .TplVar}} ==> {{$tplVar}}
</div>
<div>
  {{.html}}
  <!-- 模板函數 -->
  {{str2Html .html}}
</div>
<!-- 編碼 htmlquote函數-->
{{.Pipe | htmlquote}}

定義模板嵌套

{{define "test"}} 定義的模板塊 {{end}}

<html>
  <head></head>
  <body>
    {{template "test"}}
  </body>
</html>

實戰課 models 的建立

在 models 目錄下創建 models.go 文件(別搞混了,和我們之前的那個 xorm 不是一個哈)

// controllers/default.go
package controllers
import (
    "github.com/astaxie/beego"
)
type MainController struct {
    beego.Controller
}

func (c *MainController) Get() {
    c.TplName = "home.html"
}

// models/models.go 注意orm中後面是帶雙引號

type Category struct {
    Id              int64
    Title           string
    Created         time.Time `orm:"index;auto_now_add;type(datetime)"`
    Views           int64     `orm:"index"`
    TopicTime       time.Time `orm:"index;auto_now_add;type(datetime)"`
    TopicCount      int64
    TopicLastUserId int64
}

type Topic struct {
    Id              int64
    Uid             int64
    Title           string
    Content         string `orm:size(5000)`
    Attachment      string
    Created         time.Time `orm:"index;auto_now_add;type(datetime)"`
    Updated         time.Time `orm:"index;auto_now_add;type(datetime)"`
    Views           int64     `orm:"index"`
    Author          string
    ReplyTime       time.Time
    ReplyCount      int64
    ReplyLastUserId int64
}

func RegisterDB() {
    if !com.IsExist(_DB_NAME) {
        os.MkdirAll(path.Dir(_DB_NAME), os.ModePerm)
        os.Create(_DB_NAME)
    }
    orm.RegisterModel(new(Category), new(Topic))
    orm.RegisterDriver(_SQLITE3_DERIVER, orm.DRSqlite)
    //    強制要求必須有一個數據庫叫default 不管你有幾個數據庫 最大連接數10
    orm.RegisterDataBase("default", _SQLITE3_DERIVER, _DB_NAME, 10)
}


// main.go
package main
import (
    "beeapp/controllers"
    "beeapp/models"
    _ "beeapp/routers"
    "github.com/astaxie/beego"
    "github.com/astaxie/beego/orm"
)
func init()  {
    models.RegisterDB()
}
func main() {
    orm.Debug = true //調度模式
    //自動建表
    orm.RunSyncdb("default",false,true)
    beego.Router("/",&controllers.MainController{})
    beego.Run()
}

登錄及分類管理

拆分模板,將上例中的模板內容拆分成不同塊以備後續開發復用使用。如將網頁頭問提取出來命名為T_header.tpl

{{define "header"}}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
    />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="shortcut icon" href="/static/img/favicon.ico" />
    <link rel="stylesheet" href="/static/css/bootstrap.min.css" />
    <title>首頁</title>
  </head>
  <body style="padding-top: 70px">
    {{end}}
  </body>
</html>

在 home.html 模板中刪除對應的內容,並改為 beego 模板引入語法;定義模板要用{{define "header"}} {{end}}

注意最後面的那個.,如果在模板中使用使用變量則需要這個點,如果是純靜態資源可以省略

{{template "header" .}}
<!-- 模板輸出變量{{.變量名}} -->

這裡使用 glide 來做包管理工具,也會碰到 go get golang.org/x/不能下載問題,可以使用添加映像來管理;這裡只添加了 tools net sys
~~坑已經狠狠的踩過了,千萬不要用 glide~~ 還有個坑就是 terminal 翻牆

glide mirror set https://golang.org/x/mobile https://github.com/golang/mobile --vcs git
glide mirror set https://golang.org/x/crypto https://github.com/golang/crypto --vcs git
glide mirror set https://golang.org/x/net https://github.com/golang/net --vcs git
glide mirror set https://golang.org/x/tools https://github.com/golang/tools --vcs git
glide mirror set https://golang.org/x/text https://github.com/golang/text --vcs git
glide mirror set https://golang.org/x/image https://github.com/golang/image --vcs git
glide mirror set https://golang.org/x/sys https://github.com/golang/sys --vcs git

別改一個標題請使用 dep

github,遇到 golang.org 下載不了問題看這裡 。 基本上就是解決 terminal 下科學上網問題

cate 列表業務

<!-- category模板 -->
{{template "header" .}} {{template "navbar" .}}
<div class="container">
  <form class="form-inline" action="/cate" method="get">
    <div class="form-group">
      <label for="cate_name">類別名稱</label>
      <input
        type="text"
        style="width: 260px"
        class="form-control"
        id="cate_name"
        name="catename"
        placeholder="Please enter category name"
      />
      <input type="hidden" name="op" value="add" />
    </div>
    <button type="submit" class="btn btn-default">添加</button>
  </form>
  <table class="table table-striped">
    <thead>
      <th>#</th>
      <th>名稱</th>
      <th>文章數</th>
      <th>操作</th>
    </thead>
    <tbody>
      {{range .Categories}}
      <td>{{.Id}}</td>
      <td>{{.Title}}</td>
      <td>{{.TopicCount}}</td>
      <td>
        <a href="/cate?op=del&id={{.Id}}">刪除</a>
      </td>
      {{end}}
    </tbody>
  </table>
</div>
{{template "footer" .}}

寫業務

// CategoryController
package controllers

import (
    "beeapp/models"
    "github.com/astaxie/beego"
)

type CategoryController struct {
    beego.Controller
}

func (c *CategoryController) Get() {
    op := c.Input().Get("op")

    // 添加 刪除 顯示列表
    switch op {
    case "add":
        name := c.Input().Get("catename")
        if len(name) == 0 {
            break
        }

        err := models.AddCategory(name)
        if err != nil {
            beego.Error(err)
        }
        //添加成功 重定向cate
        c.Redirect("/cate", 301)
        // 記得return
        return

    case "del":
        id := c.Input().Get("id")
        if len(id) == 0 {
            break
        }
        err := models.DeleteCategory(id)
        if err != nil {
            beego.Error(err)
        }
        c.Redirect("/cate", 301)
        return

    }

    c.Data["Title"] = "分類"
    c.Data["IsCategory"] = true
    c.TplName = "category.html"
    var err error
    c.Data["Categories"], err = models.GetAllCategories()
    if err != nil {
        beego.Error(err)
    }
}
// models中添加如下方法
// 添加分類

func AddCategory(name string) error {
    o := orm.NewOrm()
    cate := &Category{Title: name}
    qs := o.QueryTable("category")
    err := qs.Filter("title", name).One(cate)
    if err == nil {
        //err為空說明找到了
        return err
    }
    // 不存在 要做一個insert
    _, err = o.Insert(cate)
    if err != nil {
        return err
    }
    return nil
}

func GetAllCategories() ([]*Category, error) {
    o := orm.NewOrm()
    cates := make([]*Category, 0)
    qs := o.QueryTable("category")
    //注意下面的取址符號
    _, err := qs.All(&cates)
    return cates, err
}

func DeleteCategory(id string) error {
    cid, err := strconv.ParseInt(id, 10, 64)
    if err != nil {
        return err
    }
    o := orm.NewOrm()
    cate := &Category{Id: cid}
    _, err = o.Delete(cate)
    return err
}

simple http coookie

package main

import (
    "io"
    "strings"
    "net/http"
)

func main() {
   http.HandleFunc("/",Cookie)
   http.HandleFunc("/2",Cookie2)
   http.ListenAndServe(":9090",nil)
}

func Cookie(w http.ResponseWriter, r *http.Request) {
    //第一種設置方法
    ck := &http.Cookie{
        Name:   "myCookie",
        Value:  "hello",
        Path:   "/",
        Domain: "localhost",
        MaxAge: 120,
    }
    http.SetCookie(w, ck)
    ck2, err := r.Cookie("myCookie")
    if err != nil {
        io.WriteString(w, err.Error())
        return
    }
    io.WriteString(w, ck2.Value)
}


func Cookie2(w http.ResponseWriter, r *http.Request) {
    //第二種設置方法
    ck := &http.Cookie{
        Name:   "myCookie",
        Value:  strings.Replace("hello World"," ","%20",-1), //空格在cookie中是非法字符,需要替換處理,將其替換成非空格字符,注意cookie中的非法字符
        Path:   "/",
        Domain: "localhost",
        MaxAge: 120,
    }
    w.Header().Set("Set-Cookie",ck.String())
    ck2, err := r.Cookie("myCookie")
    if err != nil {
        io.WriteString(w, err.Error())
        return
    }
    io.WriteString(w, ck2.Value)
}

主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/6717

(0)
Walker的頭像Walker
上一篇 2026年3月8日 15:11
下一篇 2026年3月9日 12:56

相關推薦

  • 編程基礎 0012_Go_Web與網絡編程精華

    Go Web 與網絡編程精華 知識來源:- 《Building Web Apps with Go》- 《Go API 編程》- 《Go Web 編程》(Go Web Programming, Sau Sheong Chang)- 《Go 網絡編程》(Network Programming with Go)- 《Mastering Go Web Service…

    後端開發 2026年3月6日
    5400
  • Go工程師體系課 009

    其它一些功能 個人中心 收藏 管理收貨地址(增刪改查) 留言 拷貝inventory_srv--> userop_srv 查詢替換所有的inventory Elasticsearch 深度解析文檔 1. 甚麼是Elasticsearch Elasticsearch是一個基於Apache Lucene構建的分布式、RESTful搜索和分析引擎,能夠快速地…

    後端開發 2026年3月7日
    5900
  • Go工程師體系課 011

    查詢的倒排索引 1. 甚麼是倒排索引? 倒排索引(Inverted Index)是一種數據結構,用於快速查找包含特定詞彙的文檔。它是搜索引擎的核心技術之一。 1.1 基本概念 正排索引:文檔 ID → 文檔內容(詞列表) 倒排索引:詞 → 包含該詞的文檔 ID 列表 1.2 為甚麼叫"倒排"? 倒排索引將傳統的"文檔包含哪些詞"的關係倒轉為"詞出現在哪些文檔…

    後端開發 2026年3月7日
    5500
  • 編程基礎 0009_testing詳解

    Go testing 詳解 目錄 testing 包基礎 表格驅動測試 子測試 t.Run 基準測試 Benchmark 測試覆蓋率 TestMain httptest 包 Mock 和接口測試技巧 模糊測試 Fuzz 1. testing 包基礎 1.1 測試文件和函數命名規則 Go 測試遵循嚴格的命名約定: 測試文件以 _test.go 結尾(如 use…

    後端開發 2026年3月6日
    6600
  • Go工程師體系課 006

    項目結構說明:user-web 模塊 user-web 是 joyshop_api 工程中的用戶服務 Web 層模塊,負責處理用戶相關的 HTTP 請求、參數校驗、業務路由以及調用後端接口等功能。以下是目錄結構說明: user-web/ ├── api/ # 控制器層,定義業務接口處理邏輯 ├── config/ # 配置模塊,包含系統配置結構體及讀取邏輯 …

    後端開發 2026年3月7日
    5500
簡體中文 繁體中文 English