beego控制器介绍
控制器介绍
提示:在 v1.6 中,此文档所涉及的 API 有重大变更,
this.ServeJson()更改为this.ServeJSON(),this.TplNames更改为this.TplName。
基于 beego 的 Controller 设计,只需要匿名组合 beego.Controller 就可以了,如下所示:
type xxxController struct {
beego.Controller
}
beego.Controller 实现了接口 beego.ControllerInterface,beego.ControllerInterface 定义了如下函数:
Init(ct *context.Context, childName string, app interface{})
这个函数主要初始化了 Context、相应的 Controller 名称,模板名,初始化模板参数的容器 Data,app 即为当前执行的 Controller 的 reflecttype,这个 app 可以用来执行子类的方法。
Prepare()
这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些 Method 方法之前执行,用户可以重写这个函数实现类似用户验证之类。
Get()
如果用户请求的 HTTP Method 是 GET,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Get 请求。
Post()
如果用户请求的 HTTP Method 是 POST,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Post 请求。
Delete()
如果用户请求的 HTTP Method 是 DELETE,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Delete 请求。
Put()
如果用户请求的 HTTP Method 是 PUT,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Put 请求.
Head()
如果用户请求的 HTTP Method 是 HEAD,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Head 请求。
Patch()
如果用户请求的 HTTP Method 是 PATCH,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Patch 请求.
Options()
如果用户请求的HTTP Method是OPTIONS,那么就执行该函数,默认是 405,用户继承的子 struct 中可以实现了该方法以处理 Options 请求。
Finish()
这个函数是在执行完相应的 HTTP Method 方法之后执行的,默认是空,用户可以在子 struct 中重写这个函数,执行例如数据库关闭,清理数据之类的工作。
Render() error
这个函数主要用来实现渲染模板,如果 beego.AutoRender 为 true 的情况下才会执行。
所以通过子 struct 的方法重写,用户就可以实现自己的逻辑,接下来我们看一个实际的例子:
type AddController struct {
beego.Controller
}
func (this *AddController) Prepare() {
}
func (this *AddController) Get() {
this.Data["content"] = "value"
this.Layout = "admin/layout.html"
this.TplName = "admin/add.tpl"
}
func (this *AddController) Post() {
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp models.PkgEntity
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
models.InsertPkg(pp)
pk = models.GetCruPkg(pkgname)
}
var at models.Article
at.Pkgid = pk.Id
at.Content = content
models.InsertArticle(at)
this.Ctx.Redirect(302, "/admin/index")
}
从上面的例子可以看出来,通过重写方法可以实现对应 method 的逻辑,实现 RESTful 结构的逻辑处理。
下面我们再来看一种比较流行的架构,首先实现一个自己的基类 baseController,实现一些初始化的方法,然后其他所有的逻辑继承自该基类:
type NestPreparer interface {
NestPrepare()
}
// baseRouter implemented global settings for all other routers.
type baseController struct {
beego.Controller
i18n.Locale
user models.User
isLogin bool
}
// Prepare implemented Prepare method for baseRouter.
func (this *baseController) Prepare() {
// page start time
this.Data["PageStartTime"] = time.Now()
// Setting properties.
this.Data["AppDescription"] = utils.AppDescription
this.Data["AppKeywords"] = utils.AppKeywords
this.Data["AppName"] = utils.AppName
this.Data["AppVer"] = utils.AppVer
this.Data["AppUrl"] = utils.AppUrl
this.Data["AppLogo"] = utils.AppLogo
this.Data["AvatarURL"] = utils.AvatarURL
this.Data["IsProMode"] = utils.IsProMode
if app, ok := this.AppController.(NestPreparer); ok {
app.NestPrepare()
}
}
/*
分析一线init方法的实现过程
c.AppController 代表接口,可以调用子类的方法
this.AppController.(NestPreparer)
判断当前运行的 Controller 是否是 NestPreparer 实现
// Init generates default values of controller operations.
func (c *Controller) Init(ctx *context.Context, controllerName, actionName string, app interface{}) {
c.Layout = ""
c.TplName = ""
c.controllerName = controllerName
c.actionName = actionName
c.Ctx = ctx
c.TplExt = "tpl"
c.AppController = app
c.EnableRender = true
c.EnableXSRF = true
c.Data = ctx.Input.Data()
c.methodMapping = make(map[string]func())
}
*/
上面定义了基类,大概是初始化了一些变量,最后有一个 Init 函数中那个 app 的应用,判断当前运行的 Controller 是否是 NestPreparer 实现,如果是的话调用子类的方法,下面我们来看一下 NestPreparer 的实现:
type BaseAdminRouter struct {
baseController
}
func (this *BaseAdminRouter) NestPrepare() {
if this.CheckActiveRedirect() {
return
}
// if user isn't admin, then logout user
if !this.user.IsAdmin {
models.LogoutUser(&this.Controller)
// write flash message
this.FlashWrite("NotPermit", "true")
this.Redirect("/login", 302)
return
}
// current in admin page
this.Data["IsAdmin"] = true
if app, ok := this.AppController.(ModelPreparer); ok {
app.ModelPrepare()
return
}
}
func (this *BaseAdminRouter) Get(){
this.TplName = "Get.tpl"
}
func (this *BaseAdminRouter) Post(){
this.TplName = "Post.tpl"
}
这样我们的执行器执行的逻辑是这样的,首先执行 Prepare,这个就是 Go 语言中 struct 中寻找方法的顺序,依次往父类寻找。执行 BaseAdminRouter 时,查找他是否有 Prepare 方法,没有就寻找 baseController,找到了,那么就执行逻辑,然后在 baseController 里面的 this.AppController 即为当前执行的控制器 BaseAdminRouter,因为会执行 BaseAdminRouter.NestPrepare 方法。然后开始执行相应的 Get 方法或者 Post 方法。
提前终止运行
我们应用中经常会遇到这样的情况,在 Prepare 阶段进行判断,如果用户认证不通过,就输出一段信息,然后直接中止进程,之后的 Post、Get 之类的不再执行,那么如何终止呢?可以使用 StopRun 来终止执行逻辑,可以在任意的地方执行。
type RController struct {
beego.Controller
}
func (this *RController) Prepare() {
this.Data["json"] = map[string]interface{}{"name": "astaxie"}
this.ServeJSON()
this.StopRun()
}
调用 StopRun 之后,如果你还定义了 Finish 函数就不会再执行,如果需要释放资源,那么请自己在调用 StopRun 之前手工调用 Finish 函数。
在表单中使用 PUT 方法
首先要说明, 在 XHTML 1.x 标准中, 表单只支持 GET 或者 POST 方法. 虽然说根据标准, 你不应该将表单提交到 PUT 方法, 但是如果你真想的话, 也很容易, 通常可以这么做:
首先表单本身还是使用 POST 方法提交, 但是可以在表单中添加一个隐藏字段:
<form method="post" ...>
<input type="hidden" name="_method" value="put" />
接着在 Beego 中添加一个过滤器来判断是否将请求当做 PUT 来解析:
var FilterMethod = func(ctx *context.Context) {
if ctx.BeegoInput.Query("_method")!="" && ctx.BeegoInput.IsPost(){
ctx.Request.Method = ctx.BeegoInput.Query("_method")
}
}
beego.InsertFilter("*", beego.BeforeRouter, FilterMethod)
beego控制器介绍的更多相关文章
- beego——控制器函数
基于beego的Controller设计,只需要匿名组合beego.Controller就可以,如下所示: type xxxController struct { beego.Controller } ...
- 7. Jmeter-逻辑控制器介绍与使用
逻辑控制器介绍与使用 如果(if)控制器 事物控制器 循环控制器 while controller critical section controller foreach控制器 include con ...
- PID控制器介绍
在维基百科上查到的PID的介绍,收藏一下,慢慢看. https://zh.wikipedia.org/wiki/PID%E6%8E%A7%E5%88%B6%E5%99%A8#%E6%AF%94%E4% ...
- CAN协议学习(二)MCAN控制器介绍
更多细节请参看MCAN2文档mcan2_ps.pdf. 一.MCAN2简介 MCAN2是Mentor公司开发的一个CAN2.0网络控制器的软核,初版2001年末版2006年.MCAN 2控制器实现了B ...
- beego学习2 控制器与路由
beego控制器 controller目录新建test.go文件 结构体集成beego.Controller 控制名需大写,否则为私有方法 package controllers import ( & ...
- iOS:模态弹出窗控制器UIPopoverPresentationController
模态弹出窗控制器:UIPopoverPresentationController 实质:就是将内容控制器包装成PopoverPresentationController的形式,然后再模态出来,必须指定 ...
- ARM 之LCD和LCD控制器
既然提到 了LCD那么我们首先必须要了解的就是他的种类,CD(liquid crystal display), 即液晶显示器,是这一种采用了液晶控制透光度计数来实现色彩的显示器,他与传统的CRT显示 ...
- ABP官方文档翻译 6.1.1 MVC控制器
ASP.NET MVC控制器 介绍 AbpController基类 本地化 其他 过滤器 异常处理和结果包装 审计日志 验证 授权 工作单元 介绍 ABP通过Abp.Web.Mvc nuget包集成到 ...
- ABP官方文档翻译 5.1 Web API控制器
ASP.NET Web API控制器 介绍 AbpApiController基类 本地化 其他 过滤器 审计日志 授权 反伪造过滤器 工作单元 结果包装和异常处理 结果缓存 校验 模型绑定器 介绍 A ...
随机推荐
- 一起了解 .Net Foundation 项目 No.1
.Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Akka.NET Akka ...
- 记一次kubernetes驱逐踩坑
最近在公司的线上服务器上发现了一个现象: 将某个node的kubelet短暂的停掉之后,其上的pod马上会被驱逐,这让笔者大吃一惊,印象之中,停掉kubelet后,该node会变为NotReady状态 ...
- Android Studio 3.6 正式版终于发布了
Google 下载地址 百度云 下载地址 密码:epl9 如题,Android Studio 3.6 正式版终于发布了,值得兴奋呀,毕竟 3.5 大版本更新也已经差不多半年了,撒花撒花!这次更新又更新 ...
- 北京智和信通IT运维管理系统二次开发服务提供商
随着云计算.大数据.物联网.移动互联网.人工智能.5G等高新技术的快速发展,数据中心及网络基础设施呈现出井喷式的增长模式,对设备商来说,多.快.好.省的实现定制化网络管理开发,可极大的扩充设备适用范围 ...
- 实验一 GIT 代码版本管理
实验一 GIT 代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2)熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git ini ...
- Shiro知识初探(更新中)
Shiro 是当下常见的安全框架,主要用于用户验证和授权操作. RBAC 是当下权限系统的设计基础,同时有两种解释:一: Role-Based Access Control,基于角色的访问控制即,你要 ...
- PPT导出为图片
使用Aspose组件导出 Aspose有Aspose.Slides.dll,可以无需安装office,进行读写PPT文件. Aspose可能通过Aspose.Slides.NET安装 简单的导出图片d ...
- C# 四则运算及省市选择及日月选择
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- pycharm中新建Vue项目时没有vue.js的解决办法
可能很多小伙伴在使用pycharm 1,新建vue项目的时候并没有发现vue.js的名字, 2,新建.vue文件(即单文件组件)的时候没有 下面就来帮助大家一下,仅供参考 如图: 1.首先我们打开设置 ...
- 有关鼠标在页面body获取点击事件的问题
首先说到这个问题我们先来谈谈body的高度问题,关于body高度的设置. 有些小伙伴可能就会说这个是多么的简单,直接进行如下操作不就可以了 body{ height:100%; } 这个设置虽然是想法 ...