摘要
本文内容转自网络,个人学习记录使用,请勿传播
安装
获取依赖包
1 | go get github.com/astaxie/beego |
最小应用
1 | package main |
创建项目
1 | bee create hello |
配置
开发模式
- 开发模式下,如果你的目录不存在views目录,那么会出现类似下面的错误提示:
[W] [stat views: no such file or directory] - 模板会自动重新加载不缓存。
- 如果服务端出错,那么就会在浏览器端显示debug信息
1 | beego.RunMode = "pro" |
路由设置
路由的主要功能是实现从请求地址到实现方法,beego中封装了Controller,所以路由是从路径到ControllerInterface的过程,ControllerInterface的方法有如下:
1 | type ControllerInterface interface { |
这些方法beego.Controller都已经实现了,所以只要用户定义struct的时候匿名包含就可以了。当然更灵活的方法就是用户可以去自定义类似的方法,然后实现自己的逻辑。
1 | beego.Router("/", &controllers.MainController{}) |
多种路由配置
为了用户更加方便的路由设置,beego参考了sinatra的路由实现,支持多种方式的路由:
1 | * `beego.Router("/api/:id([0-9]+)", &controllers.RController{}) |
静态文件
Go语言内部其实已经提供了http.ServeFile,通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装,通过下面的方式进行静态文件注册:
- 第一个参数是路径,url路径信息
- 第二个参数是静态文件目录(相对应用所在的目录)
1 | beego.SetStaticPath("/static","public") |
beego支持多个目录的静态文件注册,用户可以注册如下的静态文件目录:
1 | beego.SetStaticPath("/images","images") |
过滤和中间件
beego支持自定义过滤中间件,例如安全验证,强制跳转等
验证用户名是否是admin,应用于全部的请求
1 | var FilterUser = func(w http.ResponseWriter, r *http.Request) { |
通过参数进行过滤,如果匹配参数就执行
1 | beego.Router("/:id([0-9]+)", &admin.EditController{}) |
通过前缀过滤
1 | beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) { |
控制器
基于beego的Controller设计,只需要匿名组合beego.Controller就可以了,如下所示:
1 | type xxxController struct { |
beego.Controller实现了接口beego.ControllerInterface
1 | type AddController struct { |
beego.ControllerInterface定义了如下函数:
Init(ct *Context, cn string)
这个函数主要初始化了Context、相应的Controller名称,模板名,初始化模板参数的容器Data
Prepare()
这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些Method方法之前执行,用户可以重写这个函数实现类似用户验证之类。
Get()
如果用户请求的HTTP Method是GET, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Get请求.
Post()
如果用户请求的HTTP Method是POST, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Post请求.
Delete()
如果用户请求的HTTP Method是DELETE, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Delete请求.
Put()
如果用户请求的HTTP Method是PUT, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Put请求.
Head()
如果用户请求的HTTP Method是HEAD, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Head请求.
Patch()
如果用户请求的HTTP Method是PATCH, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Patch请求.
Options()
如果用户请求的HTTP Method是OPTIONS, 那么就执行该函数,默认是403,用户继承的子struct中可以实现了该方法以处理Options请求.
Finish()
这个函数实在执行完相应的http Method方法之后执行的,默认是空,用户可以在子Strcut中重写这个函数,执行例如数据库关闭,清理数据之类的工作
Render() error
这个函数主要用来实现渲染模板,如果beego.AutoRender为true的情况下才会执行。
模板
模板目录
beego中默认的模板目录是views,用户可以把你的模板文件放到该目录下,beego会自动在该目录下的所有模板文件进行解析并缓存,开发模式下会每次重新解析,不做缓存。当然用户可以通过如下的方式改变模板的目录:
1 | beego.ViewsPath = "/myviewpath" |
自动渲染
beego中用户无需手动的调用渲染输出模板,beego会自动的在调用玩相应的method方法之后调用Render函数,当然如果你的应用是不需要模板输出的,那么你可以在配置文件或者在main.go中设置关闭自动渲染。
1 | autorender = false |
模板数据
模板中的数据是通过在Controller中"this.Data"获取的,所以如果你想在模板中获取内容
1 | {{.Content}} |
那么你需要在Controller中如下设置:
1 | this.Data["Context"] = "value" |
模板名称
beego采用了Go语言内置的模板引擎,所有模板的语法和Go的一模一样,至于如何写模板文件,详细的请参考模板教程。
用户通过在Controller的对应方法中设置相应的模板名称,beego会自动的在viewpath目录下查询该文件并渲染,例如下面的设置,beego会在admin下面找add.tpl文件进行渲染:
1 | this.TplNames = "admin/add.tpl" |
我们看到上面的模板后缀名是tpl,beego默认情况下支持tpl和html后缀名的模板文件,如果你的后缀名不是这两种,请进行如下设置:
1 | beego.AddTemplateExt("你文件的后缀名") |
当你设置了自动渲染,然后在你的Controller中没有设置任何的TplNames,那么beego会自动设置你的模板文件如下:
1 | c.TplNames = c.ChildName + "/" + c.Ctx.Request.Method + "." + c.TplExt |
也就是你对应的Controller名字+请求方法名.模板后缀,也就是如果你的Controller名是AddController,请求方法是POST,默认的文件后缀是tpl,那么就会默认请求/viewpath/AddController/POST.tpl文件。
lauout设计
beego支持layout设计,例如你在管理系统中,其实整个的管理界面是固定的,支会变化中间的部分,那么你可以通过如下的设置:
1 | this.Layout = "admin/layout.html" |
beego就会首先解析TplNames指定的文件,获取内容赋值给LayoutContent,然后最后渲染layout.html文件。
目前采用首先把目录下所有的文件进行缓存,所以用户还可以通过类似这样的方式实现layout:
1 | {{template "header.html"}} |
模板函数
beego支持用户定义模板函数,但是必须在beego.Run()调用之前,设置如下:
1 | func hello(in string)(out string){ |
定义之后你就可以在模板中这样使用了:
1 | {{.Content | hi}} |
目前beego内置的模板函数有如下:
1 | markdown |
request处理
我们经常需要获取用户传递的数据,包括Get、POST等方式的请求,beego里面会自动解析这些数据,你可以通过如下方式获取数据
GetString(key string) stringGetInt(key string) (int64, error)GetBool(key string) (bool, error)
1 | func (this *MainController) Post() { |
如果你需要的数据可能是其他类型的,例如是int类型而不是int64,那么你需要这样处理:
1 | func (this *MainController) Post() { |
更多其他的request的信息,用户可以通过this.Ctx.Request获取信息,关于该对象的属性和方法参考手册Request
文件上传
在beego中你可以很容易的处理文件上传,就是别忘记在你的form表单中增加这个属性enctype="multipart/form-data",否者你的浏览器不会传输你的上传文件。
文件上传之后一般是放在系统的内存里面,如果文件的size大于设置的缓存内存大小,那么就放在临时文件中,默认的缓存内存是64M,你可以通过如下来调整这个缓存内存大小:
1 | beego.MaxMemory = 1<<22 |
beego提供了两个很方便的方法来处理文件上传:
GetFile(key string) (multipart.File, *multipart.FileHeader, error)- 该方法主要用于用户读取表单中的文件名the_file,然后返回相应的信息,用户根据这些变量来处理文件上传:过滤、保存文件等。
SaveToFile(fromfile, tofile string) error- 该方法是在GetFile的基础上实现了快速保存的功能
1 | func (this *MainController) Post() { |
JSON和XML输出
beego当初设计的时候就考虑了API功能的设计,而我们在设计API的时候经常是输出JSON或者XML数据,那么beego提供了这样的方式直接输出:
JSON数据直接输出,设置content-type为application/json:
1 | func (this *AddController) Get() { |
XML数据直接输出,设置content-type为application/xml:
1 | func (this *AddController) Get() { |
跳转和错误
我们在做Web开发的时候,经常会遇到页面调整和错误处理,beego这这方面也进行了考虑,通过Redirect方法来进行跳转:
1 | func (this *AddController) Get() { |
response处理
response可能会有集中情况:
- 模板输出
- 模板输出上面模板介绍里面已经介绍,beego会在执行完相应的Controller里面的对应的Method之后输出到模板。
- 跳转
- 字符串输出
1 | this.Ctx.WriteString("ok") |
Sessions
beego内置了session模块,目前session模块支持的后端引擎包括memory、file、mysql、redis四中,用户也可以根据相应的interface实现自己的引擎。
1 | beego.SessionOn = true |
通过这种方式就可以开启session,如何使用session,请看下面的例子:
1 | func (this *MainController) Get() { |
SetSession(name string, value interface{})GetSession(name string) interface{}DelSession(name string)
session操作主要有设置session、获取session、删除session
当然你要可以通过下面的方式自己控制相应的逻辑这些逻辑:
1 | sess:=this.StartSession() |
sess对象具有如下方法:
sess.Set()sess.Get()sess.Delete()sess.SessionID()- 建议大家采用SetSession、GetSession、DelSession三个方法来操作,避免自己在操作的过程中资源没释放的问题。
关于Session模块使用中的一些参数设置:
1 | SessionOn |
当SessionProvider为file时,SessionSavePath是只保存文件的目录,如下所示:
1 | beego.SessionProvider = "file" |
当SessionProvider为mysql时,SessionSavePath是链接地址,采用go-sql-driver,如下所示:
1 | beego.SessionProvider = "mysql" |
当SessionProvider为redis时,SessionSavePath是redis的链接地址,采用了redigo,如下所示:
1 | beego.SessionProvider = "redis" |
Cache设置
beego内置了一个cache模块,实现了类似memcache的功能,缓存数据在内存中,主要的使用方法如下:
1 | var ( |
上面这个例子演示了如何使用beego的Cache模块,主要是通过beego.NewBeeCache初始化一个对象,然后设置过期时间,开启过期检测,在业务逻辑中就可以通过如下的接口进行增删改的操作:
Get(name string) interface{}Put(name string, value interface{}, expired int) errorDelete(name string) (ok bool, err error)IsExist(name string) bool
安全的Map
我们知道在Go语言里面map是非线程安全的,详细的atomic_maps。但是我们在平常的业务中经常需要用到线程安全的map,特别是在goroutine的情况下,所以beego内置了一个简单的线程安全的map:
1 | bm := NewBeeMap() |
上面演示了如何使用线程安全的Map,主要的接口有:
Get(k interface{}) interface{}Set(k interface{}, v interface{}) boolCheck(k interface{}) boolDelete(k interface{})
日志处理
beego默认有一个初始化的BeeLogger对象输出内容到stdout中,你可以通过如下的方式设置自己的输出:
1 | beego.SetLogger(*log.Logger) |
只要你的输出符合*log.Logger就可以,例如输出到文件:
1 | fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644) |
不同级别的log日志函数
Trace(v ...interface{})Debug(v ...interface{})Info(v ...interface{})Warn(v ...interface{})Error(v ...interface{})Critical(v ...interface{})
可以通过下面的方式设置不同的日志分级:
1 | beego.SetLevel(beego.LevelError) |
当代码中有很多日志输出之后,如果想上线,但是你不想输出Trace、Debug、Info等信息,那么你可以设置如下:
1 | beego.SetLevel(beego.LevelWarning) |
这样的话就不会输出小于这个level的日志,日志的排序如下:
LevelTrace、LevelDebug、LevelInfo、LevelWarning、 LevelError、LevelCritical
用户可以根据不同的级别输出不同的错误信息,如下例子所示:
Examples of log messages
1 | func internalCalculationFunc(x, y int) (result int, err error) { |
配置管理
beego支持解析ini文件, beego默认会解析当前应用下的conf/app.conf文件
通过这个文件你可以初始化很多beego的默认参数
1 | appname = beepkg |
获取配置
1 | beego.AppConfig.String("mysqluser") |
AppConfig支持如下方法
Bool(key string) (bool, error)Int(key string) (int, error)Int64(key string) (int64, error)Float(key string) (float64, error)String(key string) string
系统默认参数
beego中带有很多可配置的参数,我们来一一认识一下它们,这样有利于我们在接下来的beego开发中可以充分的发挥他们的作用:
BeeApp
beego默认启动的一个应用器入口,在应用import beego的时候,在init中已经初始化的。
AppConfig
beego的配置文件解析之后的对象,也是在init的时候初始化的,里面保存有解析conf/app.conf下面所有的参数数据
HttpAddr
应用监听地址,默认为空,监听所有的网卡IP
HttpPort
应用监听端口,默认为8080
AppName
应用名称,默认是beego
RunMode
应用的模式,默认是dev,为开发模式,在开发模式下出错会提示友好的出错页面,如前面错误描述中所述。
AutoRender
是否模板自动渲染,默认值为true,对于API类型的应用,应用需要把该选项设置为false,不需要渲染模板。
RecoverPanic
是否异常恢复,默认值为true,即当应用出现异常的情况,通过recover恢复回来,而不会导致应用异常退出。
PprofOn
是否启用pprof,默认是false,当开启之后,用户可以通过如下地址查看相应的goroutine执行情况
1 | /debug/pprof |
ViewsPath
模板路径,默认值是views
SessionOn
session是否开启,默认是false
SessionProvider
session的引擎,默认是memory
SessionName
存在客户端的cookie名称,默认值是beegosessionID
SessionGCMaxLifetime
session过期时间,默认值是3600秒
SessionSavePath
session保存路径,默认是空
UseFcgi
是否启用fastcgi,默认是false
MaxMemory
文件上传默认内存缓存大小,默认值是
第三方应用集成
beego支持第三方应用的集成,用户可以自定义http.Handler,用户可以通过如下方式进行注册路由:
1 | beego.RouterHandler("/chat/:info(.*)", sockjshandler) |
sockjshandler实现了接口http.Handler。
目前在beego的example中有支持sockjs的chat例子,示例代码如下:
1 | package main |
swagger
https://studygolang.com/articles/4271