编程基础 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日
    5700
  • Go工程师体系课 009

    其它一些功能 个人中心 收藏 管理收货地址(增删改查) 留言 拷贝inventory_srv--> userop_srv 查询替换所有的inventory Elasticsearch 深度解析文档 1. 什么是Elasticsearch Elasticsearch是一个基于Apache Lucene构建的分布式、RESTful搜索和分析引擎,能够快速地…

    后端开发 2026年3月7日
    6300
  • Go工程师体系课 011

    查询的倒排索引 1. 什么是倒排索引? 倒排索引(Inverted Index)是一种数据结构,用于快速查找包含特定词汇的文档。它是搜索引擎的核心技术之一。 1.1 基本概念 正排索引:文档 ID → 文档内容(词列表) 倒排索引:词 → 包含该词的文档 ID 列表 1.2 为什么叫"倒排"? 倒排索引将传统的"文档包含哪些词"的关系倒转为"词出现在哪些文档…

    后端开发 2026年3月7日
    6000
  • 编程基础 0009_testing详解

    Go testing 详解 目录 testing 包基础 表格驱动测试 子测试 t.Run 基准测试 Benchmark 测试覆盖率 TestMain httptest 包 Mock 和接口测试技巧 模糊测试 Fuzz 1. testing 包基础 1.1 测试文件和函数命名规则 Go 测试遵循严格的命名约定: 测试文件以 _test.go 结尾(如 use…

    后端开发 2026年3月6日
    7000
  • Go工程师体系课 006

    项目结构说明:user-web 模块 user-web 是 joyshop_api 工程中的用户服务 Web 层模块,负责处理用户相关的 HTTP 请求、参数校验、业务路由以及调用后端接口等功能。以下是目录结构说明: user-web/ ├── api/ # 控制器层,定义业务接口处理逻辑 ├── config/ # 配置模块,包含系统配置结构体及读取逻辑 …

    后端开发 2026年3月7日
    5800
简体中文 繁体中文 English