同步操作将从 goflyfox/gfstudy 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
gf
框架自建了非常强大的路由功能,提供了比任何同类框架更加出色的路由特性,支持流行的命名匹配规则、模糊匹配规则及字段匹配规则,并提供了优秀的优先级管理机制。
该方法是路由注册的最基础方法,其中的pattern
为路由注册规则字符串,在其他路由注册方法中也会使用到,参数格式如下:
[HTTPMethod:]路由规则[@域名]
其中HTTPMethod
(支持的Method:GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE
)和@域名
为非必需参数,一般来说直接给定路由规则参数即可,BindHandler
会自动绑定所有的请求方式,如果给定HTTPMethod
,那么路由规则仅会在该请求方式下有效。@域名
可以指定生效的域名名称,那么该路由规则仅会在该域名下生效。
BindHandler
是最原生的路由注册方法,在大部分场景中,我们通常使用 分组路由 方式来管理路由
示例:
// hello方法,post调用
s.BindHandler("POST:/hello", func(r *ghttp.Request) {
r.Response.Writeln("url" + r.Router.Uri)
})
回调函数注册方式是最简单且最灵活的的路由注册方式,注册的服务可以是一个实例化对象的方法地址,也可以是一个包方法地址。服务需要的数据可以通过模块内部变量形式
或者对象内部变量形式
进行管理,开发者可根据实际情况进行灵活控制。
我们可以直接通过BindHandler
方法完成回调函数的注册,在框架的开发手册中很多地方都使用了回调函数注册的方式来做演示,因为这种注册方式比较简单。
示例:
// 方法注册
s.BindHandler("/total", Total)
执行对象注册是在注册时便给定一个实例化的对象,以后每一个请求都交给该对象(同一对象)处理,该对象常驻内存不释放。服务端进程在启动时便需要初始化这些执行对象,并且这些对象需要自行负责对自身数据的并发安全维护(往往对象的成员变量应当是并发安全的,每个请求执行完毕后该对象不会销毁,其成员变量也不会释放)。
// 对象注册
c := new(Controller)
s.BindObject("POST:/object", c)
GF
框架支持分组路由的注册方式,可以给分组路由指定一个prefix
前缀(也可以直接给定/
前缀,表示注册在根路由下),在该分组下的所有路由注册都将注册在该路由前缀下。分组路由注册方式也是推荐的路由注册方式。
示例:
// 分组注册及中间件
group := s.Group("/api")
group.ALL("/all", func(r *ghttp.Request) {
r.Response.Writeln("all")
})
GF
提供了优雅的中间件请求控制方式,该方式也是主流的WebServer
提供的请求流程控制方式,基于中间件设计可以为WebServer
提供更灵活强大的插件机制。经典的中间件洋葱模型:
示例:
// 分组注册及中间件
group := s.Group("/api")
group.Middleware(MiddlewareTest)
group.ALL("/all", func(r *ghttp.Request) {
r.Response.Writeln("all")
})
请求输入依靠 ghttp.Request
对象实现,ghttp.Request
继承了底层的http.Request
对象。ghttp.Request
包含一个与当前请求对应的返回输出对象Response
,用于数据的返回处理。
可以看到Request
对象的参数获取方法非常丰富,可以分为以下几类:
Get*
: 常用方法,简化参数获取,GetRequest*
的别名。GetQuery*
: 获取GET
方式传递过来的参数,包括Query String
及Body
参数解析。GetForm*
: 获取表单方式传递过来的参数,表单方式提交的参数Content-Type
往往为application/x-www-form-urlencoded
, application/form-data
, multipart/form-data
, multipart/mixed
等等。GetRequest*
: 获取客户端提交的参数,不区分提交方式。Get*Struct
: 将指定类型的请求参数绑定到指定的struct
对象上,注意给定的参数为对象指针。绝大部分场景中往往使用Parse
方法将请求数据转换为请求对象,具体详见后续章节。GetBody/GetBodyString
: 获取客户端提交的原始数据,该数据是客户端写入到body
中的原始数据,与HTTP Method
无关,例如客户端提交JSON/XML
数据格式时可以通过该方法获取原始的提交数据。GetJson
: 自动将原始请求信息解析为gjson.Json
对象指针返回。Exit*
: 用于请求流程退出控制;ghttp.Response
对象实现了标准库的http.ResponseWriter
接口。数据输出使用Write*
相关方法实现,并且数据输出采用了Buffer
机制,因此数据的处理效率比较高。任何时候可以通过OutputBuffer
方法输出缓冲区数据到客户端,并清空缓冲区数据。
简要说明:
Write*
方法用于数据的输出,可为任意的数据格式,内部通过断言对参数做自动分析。Write*Exit
方法用于数据输出后退出当前服务方法,可用于替代return
返回方法。WriteJson*
/WriteXml
方法用于特定数据格式的输出,这是为开发者提供的简便方法。WriteTpl*
方法用于模板输出,解析并输出模板文件,也可以直接解析并输出给定的模板内容。ParseTpl*
方法用于模板解析,解析模板文件或者模板内容,返回解析后的内容。package main
import (
"github.com/gogf/gf/container/gtype"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
)
func main() {
s := g.Server()
// 常规注册
// hello方法,post调用
s.BindHandler("POST:/hello", func(r *ghttp.Request) {
r.Response.Writeln("url" + r.Router.Uri)
})
// 所有方法,url包含name参数
s.BindHandler("/:name", func(r *ghttp.Request) {
// 获取URL name参数
r.Response.Writeln("name:" + r.GetString("name"))
r.Response.Writeln("url" + r.Router.Uri)
})
// 所有方法,url包含name参数
s.BindHandler("/:name/update", func(r *ghttp.Request) {
r.Response.Writeln("name:" + r.GetString("name"))
r.Response.Writeln("url" + r.Router.Uri)
})
// 所有方法,url包含name和action参数
s.BindHandler("/:name/:action", func(r *ghttp.Request) {
r.Response.Writeln("name:" + r.GetString("name"))
r.Response.Writeln("action:" + r.GetString("action"))
r.Response.Writeln("url" + r.Router.Uri)
})
// 所有方法,url包含field属性
s.BindHandler("/user/list/{field}.html", func(r *ghttp.Request) {
// 获取URL field属性
r.Response.Writeln("field:" + r.GetString("field"))
r.Response.Writeln("url" + r.Router.Uri)
})
// 方法注册
s.BindHandler("/total", Total)
// 对象注册
c := new(Controller)
s.BindObject("POST:/object", c)
// 分组注册及中间件
group := s.Group("/api")
group.Middleware(MiddlewareTest)
group.ALL("/all", func(r *ghttp.Request) {
r.Response.Writeln("all")
})
group.GET("/get", func(r *ghttp.Request) {
r.Response.Writeln("get")
})
group.POST("/post", func(r *ghttp.Request) {
r.Response.Writeln("post")
})
// request and response
s.BindHandler("POST:/test", func(r *ghttp.Request) {
r.Response.WriteJson(g.Map{
"name":r.GetString("name"),
"age":r.GetInt("age"),
"sex":r.Header.Get("sex"),
})
})
s.SetPort(8199)
s.Run()
}
var (
total = gtype.NewInt()
)
func Total(r *ghttp.Request) {
r.Response.Write("total:", total.Add(1))
}
// 对象注册
type Controller struct{}
func (c *Controller) Index(r *ghttp.Request) {
r.Response.Write("index")
}
func (c *Controller) Show(r *ghttp.Request) {
r.Response.Write("show")
}
// 中间件
func MiddlewareTest(r *ghttp.Request) {
// 前置逻辑
r.Response.Writeln("###start")
r.Middleware.Next()
// 后置逻辑
r.Response.Writeln("###end")
}
访问结果:
### 常规注册
POST http://localhost:8199/hello
###
GET http://localhost:8199/abc
###
GET http://localhost:8199/a/add
###
GET http://localhost:8199/a/update
###
GET http://localhost:8199/user/list/11.html
### 方法注册
GET http://localhost:8199/total
### 对象注册,默认访问index
POST http://localhost:8199/object/
### 对象注册,直接访问Index
POST http://localhost:8199/object/index
### 对象注册,访问show方法
POST http://localhost:8199/object/show
### 分组,默认访问index
PUT http://localhost:8199/api/all
### 对象注册,直接访问Index
GET http://localhost:8199/api/get
### 对象注册,访问show方法
POST http://localhost:8199/api/post
### request and response
POST http://localhost:8199/test
sex:man
name=liubang&age=18
###
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。