基于beego的Controller设计,只需要匿名组合beego.Controller就可以,如下所示:

type xxxController struct {
beego.Controller
}

beego.Controller实现了接口beego.ControllerInterface,其源码定义如下:

// ControllerInterface is an interface to uniform all controller handler.
type ControllerInterface interface {
Init(ct *context.Context, controllerName, actionName string, app interface{})
Prepare()
Get()
Post()
Delete()
Put()
Head()
Patch()
Options()
Finish()
Render() error
XSRFToken() string
CheckXSRFCookie() bool
HandlerFunc(fn string) bool
URLMapping()
}

部分解释:

  (1)Init(ct *context.Context, childName string, app interface{})

    这个函数主要初始化了Context、相应的Controller名称、模板名、初始化模板参数的容器Data,

    app即为当前执行的Controller的reflecttype,这个app可以用来执行子类的方法。

  (2)Prepare()

    这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些Method方法之前执行,用户重写这个函数实现类似用户验证之类。

  (3)Get()、Post()、Delete()、Put()、Head()、Patch()、Options()

    这些函数都是用户请求的方法,用户请求的HTTP Method是什么就执行什么函数,默认是405,用户继承的子struct中可以实现该方法以处理相对应的请求。

  (4)Finish()

    这个函数是在执行完相应的HTTP Method方法之后执行的,默认是空,用户可以在子struct中重写这个函数,例如关闭数据库、清理数据之类的工作。

  (5)Render() error

    这个函数主要用来实现渲染模板,如果beego.AutoRender为true的情况下才会执行。

通过重写struct的方法,我们就可以实现自己的逻辑。

示例1:

package control

import (
"github.com/astaxie/beego"
) //重写struct,定义自己的逻辑
type AddController struct {
beego.Controller
} //定义prepare方法
func (this *AddController) Prepare() { } //定义Post方法
func (this *AddController) Post() {
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp model.PkgEntitiy
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
model.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") //返回状态码,以及跳转到对应的页面
} //之后,修改路由,就可以使用自己的逻辑处理请求
//beego.Router("/user", &controllers.AddController{})

  

下面展示一种常用的架构,首先实现一个自己的基类,实现一些初始化方法,然后,其它所有的逻辑继承自该基类。

示例2:

type NestPreparer interface {
NestPrepare()
} // baseRouter为所有其他路由器实现全局设置。
type baseController struct {
beego.Controller
i18n.Locale
user models.User
isLogin bool
}
//定义prepare方法
func (this *baseController) Prepare() { // 页面开始时间
this.Data["PageStartTime"] = time.Now() //参数配置
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()
}
} //this.Data是一个用来存储输出数据的map,可以赋值任意类型的值。

  

上面定义了基类,大概是初始化了一些变量,最后有一个init函数中那个app应用,

判断当前运行的Controller是否是NestPreparer实现,如果是的话就调用子类的方法。下面看一下NestPreparer的实现。

示例三:

type BaseAdminRouter struct {
baseController
} //定义方法
func (this *BaseAdminRouter) NestPrepare() {
if this.CheckActiveRedirect() {
return
} //当前用户不是admin,退出
if !this.user.IsAdmin {
models.LogoutUser(&this.Controller) // 写入flash信息
this.FlashWrite("NotPermit", "true")
//跳转
this.Redirect("/login", 302)
return
} // 当前管理页面
this.Data["IsAdmin"] = true if app, ok := this.AppController.(ModelPreparer); ok {
app.ModelPrepare()
return
}
} //定义get方法
func (this *BaseAdminRouter) Get() {
this.TplName = "Get.tpl"
} //定义post方法
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来终止执行逻辑,可以在任意的地方执行。

示例3:

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方法,但是如果你真想的话,也很容易,通常可以这么做:

(1)首先表单本身还是使用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——控制器函数的更多相关文章

  1. beego——模板函数

    beego 支持用户定义模板函数,但是必须在 beego.Run() 调用之前,设置如下: func hello(in string)(out string){ out = in + "wo ...

  2. beego控制器介绍

    控制器介绍 提示:在 v1.6 中,此文档所涉及的 API 有重大变更,this.ServeJson() 更改为 this.ServeJSON(),this.TplNames 更改为 this.Tpl ...

  3. webots自学笔记(六)实用控制器函数补充

    原创文章,来自"博客园,_阿龙clliu" http://www.cnblogs.com/clliu/,转载请注明原文章出处.       用Webots软件做机器人仿真时,可以编 ...

  4. AngularJS 控制器函数

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  5. beego学习2 控制器与路由

    beego控制器 controller目录新建test.go文件 结构体集成beego.Controller 控制名需大写,否则为私有方法 package controllers import ( & ...

  6. angular总结控制器的三种主要职责: 为应用中的模型设置初始状态 通过$scope对象把数据模型或函数行为暴露给视图 监视模型的变化,做出相应的动作

    m1.双向数据绑定: <body> <div ng-app ng-init="user.name='world'"> <h1>使用NG实现双边数 ...

  7. beego和gin对比

    一.对mvc的支持 beego支持完整的mvc M:Model,beego orm,把数据库数据变成object 特性 支持go的所有类型存储 更简洁的curd风格 完整实现了健壮的ORM 支持的数据 ...

  8. *** $CI =& get_instance() 用法:关于CodeIgniter中get_instance() 函数

    使用场景: 注意 get_instance 的使用场景,这个方法并不是用在控制器中的.而是用在控制器外面,比如类库中,想操作 CI 超级对象的时候,超级对象实际上就是当前控制器的实例. 你随便下个CI ...

  9. CakePHP之控制器

    控制器 控制器是MVC中的“C”. 如果你的网站使用Cake框架制作,一般根据url地址和通过路由,就会找到正确的控制器,然后控制器的动作就会被调用. 一个控制器需要解释请求数据.确保使用正确的模型. ...

随机推荐

  1. python 差分包制作-如何来制作差分包?

    继百度网盘爬虫,百度图片爬虫后这是本人第三篇有关python的文章了,由于本人之前做过嵌入式的一些东西,其中会涉及到差分包的制作,所以这篇文章想谈谈如何利用python来制作差分包,如果你对嵌入式的东 ...

  2. JS——覆盖显示,点击显示三层

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. AJax与Jsonp跨域访问

    一.JavaScript的AJax AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML) 设计AJax使用的一种重要技术 ...

  4. Ubuntu/Mac彻底解决手机ADB识别问题

    之前写过一篇同样解决手机识别问题的文章(http://www.cnblogs.com/benhero/p/4202967.html) ,不过今天在遇到特殊手机"魅族"!之前的解决方 ...

  5. 【实验一 】Spring Boot 集成 hibernate & JPA

    转眼间,2018年的十二分之一都快过完了,忙于各类事情,博客也都快一个月没更新了.今天我们继续来学习Springboot对象持久化. 首先JPA是Java持久化API,定义了一系列对象持久化的标准,而 ...

  6. va_list中的_vsntprintf使用介绍

    相信大家都用过sprintf这个函数,就是下面这样: int sprintf( char *buffer, const char *format [, argument] ... ); 在之前看到了用 ...

  7. nested exception is java.lang.VerifyError: Expecting a stackmap frame at bra

    Caused by: java.lang.VerifyError: Expecting a stackmap frame (2016-05-19 09:56:29) 转载▼ 标签: it 分类: Ja ...

  8. php ajax dom---动态增加

    js代码 <script type="text/javascript"> $(document).ready(function(){ $("#talk_sen ...

  9. 54、Android 粒子效果之雨(下雨的效果)

    核心内容: 1.绘制下雨场景的个体.雨点(直线) 2.让直线动起来 3.处理边界问题 4.构造雨点对象 5.雨点大小设置 6.速度设置和角度设置等 7.添加多个雨点 8.抽离可以在 XML 中影响的属 ...

  10. 【BZOJ3207】花神的嘲讽计划Ⅰ Hash+主席树

    [BZOJ3207]花神的嘲讽计划Ⅰ Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程序怎么跑这么快 ...