Beego 路由控制器

3.7 路由控制器

我们看看 beego 的 Controller 结构体源码

type Controller struct {
    // context data
    Ctx  *context.Context               // 与输入有关,获取数据
    Data map[interface{}]interface{}    // 与输出有关

    // route controller info
    controllerName string
    actionName     string
    methodMapping  map[string]func() //method:routertree
    AppController  interface{}

    // template data
    TplName        string               // 与输出有关
    ViewPath       string
    Layout         string               // 与输出有关
    
    // 与输出有关
    LayoutSections map[string]string // the key is the section name and the value is the template name
    TplPrefix      string
    TplExt         string
    EnableRender   bool

    // xsrf data
    _xsrfToken string
    XSRFExpire int
    EnableXSRF bool

    // session
    CruSession session.Store            // 于 session 相关
}

//ControllerInterface是统一所有控制器处理程序的接口。
// ControllerInterface is an interface to uniform all controller handler.
type ControllerInterface interface {
    // Init 是 beego 在初始化一个控制器的时候调用
    Init(ct *context.Context, controllerName, actionName string, app interface{})
    
    // Prepare 每次调用控制器方法的时候会先调用 Prepare
    Prepare()
    
    // 请求方法
    Get()
    // 请求方法
    Post()
    // 请求方法
    Delete()
    // 请求方法
    Put()
    // 请求方法
    Head()
    // 请求方法
    Patch()
    // 请求方法
    Options()
    // 请求方法
    Trace()
    
    // 当请求方法执行以后会先调用 Render 方法 然后再调用 Finish
    Finish()            // 当完成的时候调用的
    Render() error      // 用来渲染模板
    XSRFToken() string
    CheckXSRFCookie() bool
    HandlerFunc(fn string) bool
    URLMapping()
}

这里面就涉及到了 controller 的生命周期,对于 controller 他的执行流程先执行 Prepare ,一般我们不会去写 Init 函数,一般会写 Prepare 函数,接着就是他的各种请求方法,再就是 Render、Finish 。所以我们一般会写的就是 Prepare、Finish

Prepare: 函数执行之前调用,所以我们就可以通过 Prepare 做一些检查,比如说权限的检查,Prepare 可以理解为记录 controller 的时候。

Finish:用来结束 controller 的时候,比如说资源的一些释放。

获取用户提交请求数据:

在 Beego 中获取数据的方式都是对 request 对象的封装

Context => 对应到控制器就是 c.Ctx 对象,c.Ctx 中有以下 3 种方法是和请求数据相关:

  1. c.Ctx

  2. c.Ctx.Request 类似 http.Request:

    • 获取 URL 数据:

      • ParseForm + Form

      • FormValue

    • BODY:

      • x-www-form-urlencoded(自定义类型获取):

        • ParseForm + Form

        • ParseForm + PostForm

        • FormValue

        • PostFormValue

      • 其他

        • Body

  3. c.Ctx.Input

Controller 获取请求数据:

  • Get *

3.7.1 Context 获取用户请求数据范例

3.7.1.1 获取用户请求控制器范例

GetControllerAndAction() 方法获取当前请求的控制器和动作

func (c *Controller) GetControllerAndAction() (string, string) {
    return c.controllerName, c.actionName
}
package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // GetControllerAndAction() 方法获取当前请求的控制器和动作,返回两个 string
    fmt.Println(c.GetControllerAndAction())
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}
# curl 请求
[17:28:44 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header"
header

# 服务器就会输出 RequestController 控制器中的 Header 方法
[17:25:21 root@go request]#go run main.go 
2021/08/07 17:27:47.298 [I]  http server Running on http://:8080
RequestController Header

3.7.1.2 获取用户请求行范例

Ctx.Input.Method() 获取用户的请求方法

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 获取请求头信息:
    // 1.input.Method()获取请求方法
    // 2.input.Protocol()获取请求协议,
    // 3.input.URL()获取请求 URL
    // 4.input.URI()获取请求 URI

    // 定义 input 变量,赋值为 c.Ctx.Input
    input := c.Ctx.Input

    fmt.Println(input.Method(), input.Protocol(), input.URL(), input.URI())

    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}
# curl 通过 GET 方法请求
[17:55:27 root@go ~]#curl -XGET "http://127.0.0.1:8080/request/header"
header

# curl 通过 post 方法请求
[17:57:58 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header"
header[17:58:00 root@go ~]#

# 服务器端输出 post、get 请求方法,和获取请求协议、获取请求 URL、获取请求 URI
[17:55:46 root@go request]#go run main.go 
2021/08/07 17:55:47.995 [I]  http server Running on http://:8080
GET HTTP/1.1 /request/header /request/header
POST HTTP/1.1 /request/header /request/header

3.7.1.3 获取用户请求头范例

Header 源码

// Header returns request header item string by a given string.
// if non-existed, return empty string.
func (input *BeegoInput) Header(key string) string {
    return input.Context.Request.Header.Get(key)
}

范例代码

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 定义 input 变量,赋值为 c.Ctx.Input
    input := c.Ctx.Input

    // 获取 User-Agent 头部信息
    fmt.Println(input.Header("User-Agent"))

    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}
# 通过 curl 浏览器获取到的信息
[18:03:17 root@go request]#go run main.go 
2021/08/07 18:03:18.676 [I]  http server Running on http://:8080
curl/7.29.0

3.7.1.4 获取用户 RUL 和 Body 中数据

Query 源码

// Query returns input data item string by a given string.
func (input *BeegoInput) Query(key string) string {
    if val := input.Param(key); val != "" {
        return val
    }
    if input.Context.Request.Form == nil {
        input.dataLock.Lock()
        if input.Context.Request.Form == nil {
            input.Context.Request.ParseForm()
        }
        input.dataLock.Unlock()
    }
    input.dataLock.RLock()
    defer input.dataLock.RUnlock()
    return input.Context.Request.Form.Get(key)
}

范例代码

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 定义 input 变量,赋值为 c.Ctx.Input
    input := c.Ctx.Input

    // 获取用户 RUL 数据中 id 的数据
    fmt.Println(input.Query("id"))
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}

客户端请求

# 通过 rul 传递数据 id=1
[18:23:22 root@go ~]#curl -XGET "http://127.0.0.1:8080/request/header/?id=1"
header

# 通过 POST 请求传递 body 中数据 id=4
[18:27:31 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/?id=1" -d "id=4"
header

# 服务器端获取到 id=1 的数据
[18:23:00 root@go request]#go run main.go 
2021/08/07 18:23:21.044 [I]  http server Running on http://:8080
1 # 获取到用户请求 URL 中数据
4 # 获取到用户请求 Body  中数据

3.7.1.5 通过 Bind 函数获取用户 URL 和 Body 数据

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 定义 input 变量,赋值为 c.Ctx.Input
    input := c.Ctx.Input

    // 通过 Bind 函数获取用户提交数据

    // 定义 id 的变量
    var id int
    
    // Bind 对用户传入的 URL 或者是 Body 信息中的 id 进行扫描并赋值给 id 变量
    input.Bind(&id, "id")
    // 输出 id 变量
    fmt.Println(id)
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}

curl 请求

# POST 请求
[18:27:56 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/?id=1" -d "id=4"
header

# get 请求
[18:31:36 root@go ~]#curl -XGET "http://127.0.0.1:8080/request/header/?id=1"
header

# 服务器端输出 id 信息
[18:31:30 root@go request]#go run main.go 
2021/08/07 18:31:31.648 [I]  http server Running on http://:8080
4
1

以上就是 Context 对于用户请求头的处理,对于数据这块我们后面更多使用的是 Controller 中的请求处理的方法

3.7.2 Controller 获取用户请求数据范例

数据这块我们后面更多使用的是 Controller 中的请求处理的方法

3.7.2.1 获取用户传入的 URL 和 Body 数据

通过 GetInt 获取用户传入的 URL 和 Body 数据值信息,最常用的就是 GetInt、GetBool、GetString、GetStrings 这几种数据方法

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 通过 beego.Controller 获取用户传入的 kye = id 的数据,并且直接将获取到的数据转成 int 类型
    fmt.Println(c.GetInt("id"))
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}

客户端请求

# Get 请求方法
[18:31:43 root@go ~]#curl -XGET "http://127.0.0.1:8080/request/header/?id=1"
header

# Post 请求方法
[18:42:53 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/?id=1" -d "id=4"
header

# Post 请求并且传递 id 的值为 xxxx 而不是 int 类型,是一个 string 类型,通过 GetString 就能获取
[18:43:03 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/?id=1" -d "id=xxxx"
header

# 服务器端获取到用户请求数据
[18:42:47 root@go request]#go run main.go 
2021/08/07 18:42:48.631 [I]  http server Running on http://:8080
1 <nil>     # 获取到 URL 中 id 的值 nil 表示错误为空
4 <nil>     # 获取到 Post 中 id 的值 nil 表示错误为空
0 strconv.Atoi: parsing "xxxx": invalid syntax  # 获取到 id=xxxx 值为 0 并报错

3.7.2.2 获取用户提交的所有数据

Controller.Input 就是 http.parseform

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // Controller.Input 获取用户提交的所有数据信息
    fmt.Println(c.Input())
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}

curl 访问

# 通过 curl 访问 URL 传递 id=1 并且 Body 传递两个数据 id=xxx&name=zzz 
[18:50:25 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/?id=1" -d "id=xxx&name=zzz"
header

# 服务器端响应,拿到用户的 id:[xxx 1] 和 name:[zzz]] 数据
[18:53:33 root@go request]#go run main.go 
2021/08/07 18:53:35.557 [I]  http server Running on http://:8080
map[id:[xxx 1] name:[zzz]]

3.7.2.3 将用户提交数据解析成结构体(常用)

我们可以将用户的提交数据信息解析为结构体,也就是说一个 ParseForm 对应一个结构体

package main

import (
    "fmt"

    "github.com/astaxie/beego"
)

type UserLogin struct {
    UserName string
    Password string
}

type RequestController struct {
    beego.Controller
}

// 获取头里面的信息
func (c *RequestController) Header() {
    // 定义 form 变量为我们的 UserLogin 类型
    var form UserLogin

    // 解析的时候可能会出现错误,所以 ParseForm 有一个错误返回值
    err := c.ParseForm(&form)

    fmt.Println(err, form)
    c.Ctx.Output.Body([]byte("header"))
}

func main() {
    // 绑定自动路由为 RequestController
    beego.AutoRouter(&RequestController{})
    beego.Run()
}

curl 请求

# 传递 UserName=zzz&Password=123 的 body 信息
[18:53:54 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/" -d "UserName=zzz&Password=123"
header

# 服务器端响应,输出 {zzz 123} 结构体
[19:04:49 root@go request]#go run main.go 
2021/08/07 19:04:52.923 [I]  http server Running on http://:8080
<nil> {zzz 123}

但是这里就会有一个问题,代码中结构体的名称和我们提交数据的对应关系是怎么对应的,这个时候其实和 json 类型转的一样的通过 tag 标签进行转换

如果说这个时候用户提交的数据都是小写呢,我们可以看到服务器解析到一个空的结构体,并没有对应上

# 用户提交数据 username=zzz&password=123 小写
[19:07:36 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/" -d "username=zzz&password=123"
header

# 服务器端得到的是一个空的结构体
[19:04:49 root@go request]#go run main.go 
2021/08/07 19:04:52.923 [I]  http server Running on http://:8080
<nil> { }

这个时候我们就要修改代码在结构体中添加 form 标签

此时用户访问

[19:09:38 root@go ~]#curl -XPOST "http://127.0.0.1:8080/request/header/" -d "username=zzz&password=123"
header

# 服务器端拿到用户提交的 body 结构体
[19:11:10 root@go request]#go run main.go 
2021/08/07 19:11:11.884 [I]  http server Running on http://:8080
<nil> {zzz 123}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇