beego框架使用

 : jank    :   : 7418    : 2017-01-05 01:20  go


一、项目规划

1.目录结构

    博客的目录结构设计如下:

|——main.go         入口文件

|——conf            配置文件和处理模块

|——controllers     控制器入口

|——models          数据库处理模块

|——utils           辅助函数库

|——static          静态文件目录

|——views           视图库


2.beego框架:https://github.com/beego/bee

下载:go get github.com/beego/bee

更新beego版本:go get -u github.com/beego/bee


二、自定义路由器设计

1.默认的路由实现

例:

//1.路由处理函数

func fooHandler(w http.ResponseWriter, r *http.Request) {

   fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))

}

//2.添加路由信息,根据用户请求转发到对应的函数。

//Go默认的路由添加是通过函数http.Handle和http.HandleFunc等来添加,

    底层都是调用了DefaultServeMux.Handle(pattern string, handler Handler),

    这个函数会把路由信息存储在一个map信息中

    map[string]muxEntry,

    http.HandleFunc("/foo", fooHandler)

http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {

   fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))

})

//3.Go监听端口,然后接收到tcp连接会扔给Handler来处理,上面的例子默认nil

//即为http.DefaultServeMux,通过DefaultServeMux.ServeHTTP函数来进行调度,

//遍历之前存储的map路由信息,和用户访问的URL进行匹配,

    以查询对应注册的处理函数

log.Fatal(http.ListenAndServe(":8080", nil))

2.beego框架路由实现

1.目前几乎所有的Web应用路由实现都是基于http默认的路由器,

    但是Go自带的路由器有几个限制:

1.不支持参数设定,例如/user/:uid 这种泛类型匹配

2.无法很好的支持REST模式,无法限制访问的方法,例如上面的例子中,

        用户访问/foo,可以用GET、POST、DELETE、HEAD等方式访问

3.一般网站的路由规则太多了,编写繁琐。我前面自己开发了一个API应用,

           路由规则有三十几条,这种路由多了之后其实可以进一步简化,

            通过struct的方法进行一种简化

beego框架的路由器基于上面的几点限制考虑设计了一种REST方式的路由实现,

        路由设计也是基于上面Go默认设计的两点来考虑:存储路由和转发路由

2.应用中设置静态路径可以使用如下方式实现:

beego.SetStaticPath("/img","/static/img")

3.使用入门

基于这样的路由设计之后就可以解决前面所说的三个限制点,

        使用的方式如下所示:


基本的使用注册路由:

beego.BeeApp.RegisterController("/", &controllers.MainController{})

参数注册:

beego.BeeApp.RegisterController("/:param", 

            &controllers.UserController{})

正则匹配:

beego.BeeApp.RegisterController("/users/:uid([0-9]+)",

         &controllers.UserController{})


三、controller设计

1.beego的REST设计

1.前面小节介绍了路由实现了注册struct的功能,而struct中实现了REST方式,

    因此我们需要设计一个用于逻辑处理controller的基类,这里设计了两个类型

    ,一个struct、一个interface


type Controller struct {

   Ct        *Context

   Tpl       *template.Template

   Data      map[interface{}]interface{}

   ChildName string

   TplNames  string

   Layout    []string

   TplExt    string

}


type ControllerInterface interface {

   Init(ct *Context, cn string)    //初始化上下文和子类名称

   Prepare()                 //开始执行之前的一些处理

   Get()                    //method=GET的处理

   Post()                     //method=POST的处理

   Delete()                   //method=DELETE的处理

   Put()                       //method=PUT的处理

   Head()                      //method=HEAD的处理

   Patch()                     //method=PATCH的处理

   Options()                   //method=OPTIONS的处理

   Finish()                   //执行完成之后的处理       

   Render() error                 

             //执行完method对应的方法之后渲染页面

}


2.应用指南

上面beego框架中完成了controller基类的设计,那么我们在我们的应用中设计我们的方法:


package controllers


import (

   "github.com/astaxie/beego"

)


type MainController struct {

   beego.Controller

}


func (this *MainController) Get() {

   this.Data["Username"] = "jank"   //把数据放在 this.Data 中传递

   this.Data["Email"] = "astaxie@gmail.com"

   this.TplName = "index.tpl" //引入模板文件

}

上面的方式我们实现了子类MainController,实现了Get方法,那么如果用户通过

其他的方式(POST/HEAD等)来访问该资源都将返回403,而如果是Get来访问,

因为我们设置了AutoRender=true,那么在执行完Get方法之后会自动执行Render函数

index.tpl文件如下:

<!DOCTYPE html>

<html>

 <head>

   <title>beego welcome template</title>

 </head>

 <body>

   <h1>Hello, world!{{.Username}},{{.Email}}</h1> <!--模板输出内容-->

 </body>

</html>


3.post 方法实现

func (this *IndexController) Post(){

   name := this.GetString("name") //获取前台所传参数

   if name == "" {

       this.Ctx.WriteString("传递参数为空")

   }else{

       this.Ctx.WriteString("姓名:" + name) //+号为拼接符

   }

    

}

4.session模块的使用

1.开启session

#开启session,以及session配置

sessionon = true

#自定义session名

sessionname = sesjank

#自定义过期时间,默认时间是3600秒

sessiongcmaxlifetime = 86400

2.获取、设置session值

ss := this.GetSession("nick")

   if ss  == nil {

       this.Data["sessions"] = "session值为空"

       this.SetSession("nick", "jank")

   }else{

       

       this.Data["sessions"] = ss

   }

3.删除session键值

this.DelSession("nick")

5. url构建,使得controller中的方法可以url

步骤:

1.创建一个方法list:

func (this *IndexController) List() {

   this.Ctx.Output.Body([]byte("i am list"))

}

2.配置路由:

  beego.Router("/index/list", &controllers.IndexController{}, "*:List") 

获取相应的url地址:UrlFor("IndexController.List")

模板中使用:

{{urlfor "IndexController.List"}}

6.error处理

1.this.Redirect("/index", 302)//路径跳转

    2.this.Abort("401") //终止运行,页面弹出beego错误


四、正则路由


1.为了用户更加方便的路由设置,beego 参考了 sinatra 的路由实现,

    支持多种方式的路由:


beego.Router(“/api/?:id”, &controllers.RController{})


默认匹配 //匹配 /api/123 :id = 123 可以匹配/api/这个URL

beego.Router(“/api/:id”, &controllers.RController{})


默认匹配 //匹配 /api/123 :id = 123 不可以匹配/api/这个URL

beego.Router(“/api/:id([0-9]+)“, &controllers.RController{})


自定义正则匹配 //匹配 /api/123 :id = 123

beego.Router(“/user/:username([w]+)“, &controllers.RController{})


正则字符串匹配 //匹配 /user/astaxie :username = astaxie

beego.Router(“/download/*.*”, &controllers.RController{})


*匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml

beego.Router(“/download/ceshi/*“, &controllers.RController{})


*全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json

beego.Router(“/:id:int”, &controllers.RController{})


int 类型设置方式,匹配 :id为int类型,框架帮你实现了正则([0-9]+)

beego.Router(“/:hi:string”, &controllers.RController{})


string 类型设置方式,匹配 :hi为string类型。框架帮你实现了正则([w]+)

beego.Router(“/cms_:id([0-9]+).html”, &controllers.CmsController{})


带有前缀的自定义正则 //匹配 :id为正则类型。

        匹配 cms_123.html这样的url :id = 123

*/

2. Controller 中通过如下方式获取上面的变量:


this.Ctx.Input.Param(":id")

this.Ctx.Input.Param(":username")

this.Ctx.Input.Param(":splat")

this.Ctx.Input.Param(":path")

this.Ctx.Input.Param(":ext")

五、模型

1.orm的使用

安装orm包:go get github.com/astaxie/beego/orm

model文件:

package models


import (

   "github.com/astaxie/beego/orm"

    _ "github.com/go-sql-driver/mysql"

)


type User struct {

   Id         int     //Id默认为primary key,且与mysql字段名相同

   Name       string

   Age        int

   Address    string

   Sex        int

}


func init() {

   // 需要在init中注册定义的model

       orm.RegisterDataBase("default", "mysql", 

            "root:123456@/beego?charset=utf8", 30)

         //go连接池最大连接数

   orm.RegisterModel(new(User)) //register model,注册模型,

    多个model用逗号隔开

     //   orm.RunSyncdb("default", false, true)   //create table


// 使用表名前缀

// orm.RegisterModelWithPrefix("prefix_", new(User))


}

使用数据库:

    o := orm.NewOrm()

    o.Using("default") 

    // 默认使用 default,你可以指定为其他数据库,默认也可以不写


六、模板

//renderform使用,contronler

        type User struct {

            Id    int         `form:"-"`

            Name  interface{} `form:"username"`

            Age   int         `form:"age,text,年龄:"`

            Sex   string

            Intro string `form:",textarea"`

            Sub   string `form:",submit,提交:"`

        }   

        this.Data["Form"] = &User{1,"jank",23,"男","热爱书法","提交"}

//对应的模板

<form action="/" method="post">

{{.Form | renderform}}

</form>


//传递切片使模板输出,controller

        this.Data["s"] = []string{"jank", "jack", "jason", "jackson"}

//对应的模板

{{range $key, $val := .s}}

{{$val}}

{{end}}


//传递map模板输出

        mp := map[string]string{

             "江西": "南昌",

             "浙江": "杭州",

             "湖南": "长沙",

             "湖北": "武汉",

        }   

        this.Data["m"] = mp

//对应的模板

{{.m.江西}}

{{.m.浙江}}

{{.m.湖南}}

{{.m.湖北}}

        this.TplName = "info.tpl"


七、热升级

  1. 概念:比如,nginx是支持热升级的,可以用老进程服务先前链接的链接,

使用新进程服务新的链接 ,即在不停止服务的情况下完成系统的升级与运行参数修改。

那么热升级和热编译是不同的概念, 热编译是通过监控文件的变化重新编译,

然后重启进程,例如bee run就是这样的工具。

2.grace模块是beego新增的一个独立支持热重启的模块。

3.使用热升级:

 import(

   "log"

    "net/http"

    "os"

    "strconv"


   "github.com/astaxie/beego/grace"

 )


  func handler(w http.ResponseWriter, r *http.Request) {

      w.Write([]byte("WORLD!"))

      w.Write([]byte("ospid:" + strconv.Itoa(os.Getpid())))

  }


  func main() {

      mux := http.NewServeMux()

      mux.HandleFunc("/hello", handler)


      err := grace.ListenAndServe("localhost:8080", mux)

      if err != nil {

           log.Println(err)

        }

      log.Println("Server on 8080 stopped")

         os.Exit(0)

    }

打开两个终端


一个终端输入:ps -ef|grep 应用名


一个终端输入请求:curl "http://127.0.0.1:8080/hello"


热升级


kill -HUP 进程ID


打开一个终端输入请求:curl "http://127.0.0.1:8080/hello?sleep=0"


   

备案编号:赣ICP备15011386号

联系方式:qq:1150662577    邮箱:1150662577@qq.com