• 请求输入
    • Request.URLRequest.Router
    • Exit, ExitAllExitHook
  • 使用示例
    • 示例1,请求数据校验
      • 请求参数绑定+数据校验示例
    • 示例2,流程共享变量

    请求输入

    请求输入依靠 ghttp.Request 对象实现,ghttp.Request继承了底层的http.Request对象,并且包含了会话相关的CookieSession对象(每个请求都会有两个独立CookieSession对象)。此外,每个请求有一个唯一的Id(请求Id,全局唯一),用以标识每一个请求。此外,成员对象包含一个与当前请求对应的返回输出对象指针Response,用于数据的返回。

    相关方法:https://godoc.org/github.com/gogf/gf/g/net/ghttp

    1. type Request
    2. func (r *Request) AddPost(key string, value string)
    3. func (r *Request) AddQuery(key string, value string)
    4. func (r *Request) AddRouterString(key, value string)
    5. func (r *Request) BasicAuth(user, pass string, tips ...string) bool
    6. func (r *Request) IsAjaxRequest() bool
    7. func (r *Request) IsExited() bool
    8. func (r *Request) IsFileRequest() bool
    9. func (r *Request) SetPost(key string, value string)
    10. func (r *Request) SetQuery(key string, value string)
    11. func (r *Request) SetRouterString(key, value string)
    12. func (r *Request) WebSocket() (*WebSocket, error)
    13. func (r *Request) Exit()
    14. func (r *Request) ExitAll()
    15. func (r *Request) ExitHook()
    16. func (r *Request) SetParam(key string, value interface{})
    17. func (r *Request) GetParam(key string) gvar.VarRead
    18. func (r *Request) Get(key string, def ...string) string
    19. func (r *Request) GetVar(key string, def ...interface{}) gvar.VarRead
    20. func (r *Request) GetArray(key string, def ...[]string) []string
    21. func (r *Request) GetClientIp() string
    22. func (r *Request) GetFloat32(key string, def ...float32) float32
    23. func (r *Request) GetFloat64(key string, def ...float64) float64
    24. func (r *Request) GetFloats(key string, def ...[]float64) []float64
    25. func (r *Request) GetHost() string
    26. func (r *Request) GetInt(key string, def ...int) int
    27. func (r *Request) GetInterfaces(key string, def ...[]interface{}) []interface{}
    28. func (r *Request) GetInts(key string, def ...[]int) []int
    29. func (r *Request) GetJson() *gjson.Json
    30. func (r *Request) GetMap(def ...map[string]string) map[string]string
    31. func (r *Request) GetRaw() []byte
    32. func (r *Request) GetReferer() string
    33. func (r *Request) GetString(key string, def ...string) string
    34. func (r *Request) GetStrings(key string, def ...[]string) []string
    35. func (r *Request) GetToStruct(object interface{}, mapping ...map[string]string)
    36. func (r *Request) GetUint(key string, def ...uint) uint
    37. func (r *Request) GetPost(key string, def ...[]string) []string
    38. func (r *Request) GetPostArray(key string, def ...[]string) []string
    39. func (r *Request) GetPostBool(key string, def ...bool) bool
    40. func (r *Request) GetPostFloat32(key string, def ...float32) float32
    41. func (r *Request) GetPostFloat64(key string, def ...float64) float64
    42. func (r *Request) GetPostFloats(key string, def ...[]float64) []float64
    43. func (r *Request) GetPostInt(key string, def ...int) int
    44. func (r *Request) GetPostInterfaces(key string, def ...[]interface{}) []interface{}
    45. func (r *Request) GetPostInts(key string, def ...[]int) []int
    46. func (r *Request) GetPostMap(def ...map[string]string) map[string]string
    47. func (r *Request) GetPostString(key string, def ...string) string
    48. func (r *Request) GetPostStrings(key string, def ...[]string) []string
    49. func (r *Request) GetPostToStruct(object interface{}, mapping ...map[string]string)
    50. func (r *Request) GetPostUint(key string, def ...uint) uint
    51. func (r *Request) GetQuery(key string, def ...[]string) []string
    52. func (r *Request) GetQueryArray(key string, def ...[]string) []string
    53. func (r *Request) GetQueryBool(key string, def ...bool) bool
    54. func (r *Request) GetQueryFloat32(key string, def ...float32) float32
    55. func (r *Request) GetQueryFloat64(key string, def ...float64) float64
    56. func (r *Request) GetQueryFloats(key string, def ...[]float64) []float64
    57. func (r *Request) GetQueryInt(key string, def ...int) int
    58. func (r *Request) GetQueryInterfaces(key string, def ...[]interface{}) []interface{}
    59. func (r *Request) GetQueryInts(key string, def ...[]int) []int
    60. func (r *Request) GetQueryMap(def ...map[string]string) map[string]string
    61. func (r *Request) GetQueryString(key string, def ...string) string
    62. func (r *Request) GetQueryStrings(key string, def ...[]string) []string
    63. func (r *Request) GetQueryToStruct(object interface{}, mapping ...map[string]string)
    64. func (r *Request) GetQueryUint(key string, def ...uint) uint
    65. func (r *Request) GetRequest(key string, def ...[]string) []string
    66. func (r *Request) GetRequestArray(key string, def ...[]string) []string
    67. func (r *Request) GetRequestBool(key string, def ...bool) bool
    68. func (r *Request) GetRequestFloat32(key string, def ...float32) float32
    69. func (r *Request) GetRequestFloat64(key string, def ...float64) float64
    70. func (r *Request) GetRequestFloats(key string, def ...[]float64) []float64
    71. func (r *Request) GetRequestInt(key string, def ...int) int
    72. func (r *Request) GetRequestInterfaces(key string, def ...[]interface{}) []interface{}
    73. func (r *Request) GetRequestInts(key string, def ...[]int) []int
    74. func (r *Request) GetRequestMap(def ...map[string]string) map[string]string
    75. func (r *Request) GetRequestString(key string, def ...string) string
    76. func (r *Request) GetRequestStrings(key string, def ...[]string) []string
    77. func (r *Request) GetRequestToStruct(object interface{}, mapping ...map[string]string)
    78. func (r *Request) GetRequestUint(key string, def ...uint) uint
    79. func (r *Request) GetRequestVar(key string, def ...interface{}) *gvar.Var
    80. func (r *Request) GetRouterArray(key string) []string
    81. func (r *Request) GetRouterString(key string) string

    以上方法可以分为以下几类:

    1. Get*: 常用方法,简化参数获取,GetRequest*的别名;
    2. GetQuery*: 获取GET方式传递过来的Key-Value查询参数;
    3. GetPost*: 获取POST方式传递过来的Key-Value表单参数;
    4. GetRequest*: 优先查找Router路由参数中是否有指定键名的参数,如果没有则查找GET参数,如果没有则查找POST参数,如果都不存在则返回空或者默认值;
    5. GetRaw: 获取客户端提交的原始数据(二进制[]byte类型),与HTTP Method无关,例如客户端提交JSON/XML数据格式时可以通过该方法获取原始的提交数据;
    6. GetJson: 自动将原始请求信息解析为gjson.Json对象指针返回,gjson.Json对象指针具体在【gjson模块】章节中介绍;
    7. GetToStruct: 将请求参数绑定到指定的struct对象上,注意给定的参数为对象指针;
    8. SetParam/GetParam: 用于设置/获取请求流程中得共享变量,该共享变量只在该请求流程中有效,请求结束则销毁;
    9. Exit*: 用于请求流程退出控制,详见本章后续说明;

    其中,获取的参数方法可以对指定键名的数据进行自动类型转换,例如:http://127.0.0.1:8199/?amount=19.66,通过Get/GetQueryString将会返回19.66的字符串类型,GetQueryFloat32/GetQueryFloat64将会分别返回float32float64类型的数值19.66。但是,GetQueryInt/GetQueryUint将会返回19(如果参数为float类型的字符串,将会按照向下取整进行整型转换)。

    Request.URLRequest.Router

    Request.Router是匹配到的路由对象,包含路由注册信息,一般来说开发者不会用得到。Request.URL是底层请求的URL对象(继承自标准库http.Request),包含请求的URL地址信息,特别是Request.URL.Path表示请求的URI地址。

    因此,假如在服务回调函数中使用的话,Request.Router是有值的,因为只有匹配到了路由才会调用服务回调方法。但是在事件回调函数中,该对象可能为nil(表示没有匹配到服务回调函数路由)。特别是在使用事件回调对请求接口鉴权的时候,应当使用Request.URL对象获取请求的URL信息,而不是Request.Router

    Exit, ExitAllExitHook

    1. Exit: 仅退出当前执行的逻辑方法,如: 当前HOOK方法、服务方法,不退出后续的逻辑处理,可用于替代return
    2. ExitAll: 强行退出当前执行流程,当前执行方法的后续逻辑以及后续所有的逻辑方法将不再执行,常用于权限控制;
    3. ExitHook: 当路由匹配到多个HOOK方法时,默认是按照路由匹配优先级顺序执行HOOK方法。当在HOOK方法中调用ExitHook方法后,后续的HOOK方法将不会被继续执行,作用类似HOOK方法覆盖;

    使用示例

    示例1,请求数据校验

    请求参数绑定+数据校验示例

    https://github.com/gogf/gf/blob/master/geg/net/ghttp/server/request/request_validation.go

    1. package main
    2. import (
    3. "github.com/gogf/gf/g"
    4. "github.com/gogf/gf/g/net/ghttp"
    5. "github.com/gogf/gf/g/util/gvalid"
    6. )
    7. func main() {
    8. type User struct {
    9. Uid int `gvalid:"uid@min:1"`
    10. Name string `params:"username" gvalid:"username @required|length:6,30"`
    11. Pass1 string `params:"password1" gvalid:"password1@required|password3"`
    12. Pass2 string `params:"password2" gvalid:"password2@required|password3|same:password1#||两次密码不一致,请重新输入"`
    13. }
    14. s := g.Server()
    15. s.BindHandler("/user", func(r *ghttp.Request){
    16. user := new(User)
    17. r.GetToStruct(user)
    18. if err := gvalid.CheckStruct(user, nil); err != nil {
    19. r.Response.WriteJson(err.Maps())
    20. } else {
    21. r.Response.Write("ok")
    22. }
    23. })
    24. s.SetPort(8199)
    25. s.Run()
    26. }

    v1.8.0开始,参数标签支持params/param/p三种标签。

    其中,

    1. 这里使用了r.GetToStruct(user)方法将请求参数绑定到指定的user对象上,注意这里的userUser的结构体实例化指针;在struct tag中,使用params标签来指定参数名称与结构体属性名称对应关系;
    2. GetToStruct方法支持自动对结构体对象初始化,注意此时参数类型为**User,如下:
      1. user := (*User)(nil)
      2. r.GetToStruct(&user)
    3. 通过gvalid标签为gavlid数据校验包特定的校验规则标签,具体请参考【数据校验】章节;其中,密码字段的校验规则为password3,表示: 密码格式为任意6-18位的可见字符,必须包含大小写字母、数字和特殊字符
    4. 当校验染回结果非nil时,表示校验不通过,这里使用r.Response.WriteJson方法返回json结果;

    执行后,试着访问URL: http://127.0.0.1:8199/user?uid=1&name=john&password1=123&password2=456,输出结果为:

    1. {"password1":{"password3":"密码格式不合法,密码格式为任意6-18位的可见字符,必须包含大小写字母、数字和特殊字符"},"password2":{"password3":"密码格式不合法,密码格式为任意6-18位的可见字符,必须包含大小写字母、数字和特殊字符","same":"两次密码不一致,请重新输入"},"username":{"length":"字段长度为6到30个字符"}}

    假如我们访问访问URL: http://127.0.0.1:8199/user?uid=1&name=johng-cn&password1=John$123&password2=John$123,输出结果为:

    1. ok

    示例2,流程共享变量

    1. package main
    2. import (
    3. "github.com/gogf/gf/g"
    4. "github.com/gogf/gf/g/net/ghttp"
    5. )
    6. // 优先调用的HOOK
    7. func beforeServeHook1(r *ghttp.Request) {
    8. r.SetParam("name", "GoFrame")
    9. r.Response.Writeln("set name")
    10. }
    11. // 随后调用的HOOK
    12. func beforeServeHook2(r *ghttp.Request) {
    13. r.SetParam("site", "https://goframe.org")
    14. r.Response.Writeln("set site")
    15. }
    16. // 允许对同一个路由同一个事件注册多个回调函数,按照注册顺序进行优先级调用。
    17. // 为便于在路由表中对比查看优先级,这里讲HOOK回调函数单独定义为了两个函数。
    18. func main() {
    19. s := g.Server()
    20. s.BindHandler("/", func(r *ghttp.Request) {
    21. r.Response.Writeln(r.GetParam("name").String())
    22. r.Response.Writeln(r.GetParam("site").String())
    23. })
    24. s.BindHookHandler("/", ghttp.HOOK_BEFORE_SERVE, beforeServeHook1)
    25. s.BindHookHandler("/", ghttp.HOOK_BEFORE_SERVE, beforeServeHook2)
    26. s.SetPort(8199)
    27. s.Run()
    28. }

    执行后,访问 http://127.0.0.1:8199/ 后,页面输出内容为:

    1. set name
    2. set site
    3. GoFrame
    4. https://goframe.org