ghttp.Request增加对GET/POST/Router参数的设置功能

This commit is contained in:
john 2018-07-31 21:05:02 +08:00
parent 6acd228fde
commit c1d84c2a67
13 changed files with 355 additions and 323 deletions

View File

@ -20,13 +20,19 @@ func (r *Request) initPost() {
}
}
// 设置GET参数仅在ghttp.Server内有效**注意并发安全性**
// 设置POST参数仅在ghttp.Server内有效**注意并发安全性**
func (r *Request) SetPost(k string, v string) {
r.initPost()
r.PostForm[k] = []string{v}
}
func (r *Request) AddPost(k string, v string) {
r.initPost()
r.PostForm[k] = append(r.PostForm[k], v)
}
// 获得post参数
func (r *Request) GetPost(k string) string {
func (r *Request) GetPost(k string) []string {
r.initPost()
if v, ok := r.PostForm[k]; ok {
return v

View File

@ -13,23 +13,20 @@ import (
// 初始化GET请求参数
func (r *Request) initGet() {
if !r.parsedGet.Val() {
if len(r.queryVars) == 0 {
r.queryVars = r.URL.Query()
} else {
for k, v := range r.URL.Query() {
r.queryVars[k] = v
}
}
r.parsedGet.Set(true)
r.queryVars = r.URL.Query()
}
}
// 设置GET参数仅在ghttp.Server内有效**注意并发安全性**
func (r *Request) SetQuery(k string, v string) {
r.initGet()
r.queryVars[k] = []string{v}
}
// 添加GET参数构成[]string
func (r *Request) AddQuery(k string, v string) {
r.initGet()
r.queryVars[k] = append(r.queryVars[k], v)
}

View File

@ -6,6 +6,14 @@
package ghttp
func (r *Request) SetRouterString(k, v string) {
r.routerVars[k] = []string{v}
}
func (r *Request) AddRouterString(k, v string) {
r.routerVars[k] = append(r.routerVars[k], v)
}
// 获得路由解析参数
func (r *Request) GetRouterString(k string) string {
if v := r.GetRouterArray(k); v != nil {

View File

@ -1,265 +0,0 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 服务注册.
package ghttp
import (
"errors"
"strings"
"reflect"
"gitee.com/johng/gf/g/util/gstr"
)
// 绑定URI到操作函数/方法
// pattern的格式形如/user/list, put:/user, delete:/user, post:/user@johng.cn
// 支持RESTful的请求格式具体业务逻辑由绑定的处理方法来执行
func (s *Server)bindHandlerItem(pattern string, item *handlerItem) error {
if s.status == 1 {
return errors.New("server handlers cannot be changed while running")
}
return s.setHandler(pattern, item)
}
// 通过映射数组绑定URI到操作函数/方法
func (s *Server)bindHandlerByMap(m handlerMap) error {
for p, h := range m {
if err := s.bindHandlerItem(p, h); err != nil {
return err
}
}
return nil
}
// 将内置的名称按照设定的规则合并到pattern中内置名称按照{.xxx}规则命名。
// 规则1pattern中的URI包含{.struct}关键字,则替换该关键字为结构体名称;
// 规则1pattern中的URI包含{.method}关键字,则替换该关键字为方法名称;
// 规则2如果不满足规则1那么直接将防发明附加到pattern中的URI后面
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string) string {
structName = s.nameToUrlPart(structName)
methodName = s.nameToUrlPart(methodName)
pattern = strings.Replace(pattern, "{.struct}", structName, -1)
if strings.Index(pattern, "{.method}") != -1 {
return strings.Replace(pattern, "{.method}", methodName, -1)
}
// 检测域名后缀
array := strings.Split(pattern, "@")
// 分离URI(其实可能包含HTTP Method)
uri := array[0]
uri = strings.TrimRight(uri, "/") + "/" + methodName
// 加上指定域名后缀
if len(array) > 1 {
return uri + "@" + array[1]
}
return uri
}
// 将给定的名称转换为URL规范格式。
// 规范1: 全部转换为小写;
// 规范2: 方法名中间存在大写字母转换为小写URI地址以“-”号链接每个单词;
func (s *Server) nameToUrlPart(name string) string {
part := ""
for i := 0; i < len(name); i++ {
if i > 0 && gstr.IsLetterUpper(name[i]) {
part += "-"
}
part += string(name[i])
}
return strings.ToLower(part)
}
// 注意该方法是直接绑定函数的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
func (s *Server)BindHandler(pattern string, handler HandlerFunc) error {
return s.bindHandlerItem(pattern, &handlerItem{
ctype : nil,
fname : "",
faddr : handler,
})
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
func (s *Server)BindObject(pattern string, obj interface{}) error {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
sname := t.Elem().Name()
for i := 0; i < v.NumMethod(); i++ {
method := t.Method(i).Name
key := s.mergeBuildInNameToPattern(pattern, sname, method)
m[key] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(method, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 第三个参数methods支持多个方法注册多个方法以英文“,”号分隔,区分大小写
func (s *Server)BindObjectMethod(pattern string, obj interface{}, methods string) error {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
sname := t.Elem().Name()
for _, method := range strings.Split(methods, ",") {
mname := strings.TrimSpace(method)
fval := v.MethodByName(mname)
if !fval.IsValid() {
return errors.New("invalid method name:" + mname)
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem{
ctype : nil,
fname : "",
faddr : fval.Interface().(func(*Request)),
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : nil,
fname : "",
faddr : fval.Interface().(func(*Request)),
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
func (s *Server)BindObjectRest(pattern string, obj interface{}) error {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
for i := 0; i < v.NumMethod(); i++ {
name := t.Method(i).Name
method := strings.ToUpper(name)
if _, ok := s.methodsMap[method]; !ok {
continue
}
key := name + ":" + pattern
m[key] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
}
return s.bindHandlerByMap(m)
}
// 绑定控制器控制器需要实现gmvc.Controller接口
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
func (s *Server)BindController(pattern string, c Controller) error {
// 遍历控制器获取方法列表并构造成uri
m := make(handlerMap)
v := reflect.ValueOf(c)
t := v.Type()
sname := t.Elem().Name()
for i := 0; i < v.NumMethod(); i++ {
mname := t.Method(i).Name
if mname == "Init" || mname == "Shut" || mname == "Exit" {
continue
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem {
ctype : v.Elem().Type(),
fname : mname,
faddr : nil,
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : v.Elem().Type(),
fname : mname,
faddr : nil,
}
}
}
return s.bindHandlerByMap(m)
}
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
// 第三个参数methods支持多个方法注册多个方法以英文“,”号分隔,不区分大小写
func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error {
m := make(handlerMap)
v := reflect.ValueOf(c)
e := v.Type().Elem()
t := v.Elem().Type()
sname := e.Name()
for _, method := range strings.Split(methods, ",") {
mname := strings.TrimSpace(method)
if !v.MethodByName(mname).IsValid() {
return errors.New("invalid method name:" + mname)
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem {
ctype : t,
fname : mname,
faddr : nil,
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : t,
fname : mname,
faddr : nil,
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定控制器(RESTFul)控制器需要实现gmvc.Controller接口
// 方法会识别HTTP方法并做REST绑定处理例如Post方法会绑定到HTTP POST的方法请求处理Delete方法会绑定到HTTP DELETE的方法请求处理
// 因此只会绑定HTTP Method对应的方法其他方法不会自动注册绑定
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
func (s *Server)BindControllerRest(pattern string, c Controller) error {
// 遍历控制器获取方法列表并构造成uri
m := make(handlerMap)
v := reflect.ValueOf(c)
t := v.Type()
// 如果存在与HttpMethod对应名字的方法那么绑定这些方法
for i := 0; i < v.NumMethod(); i++ {
name := t.Method(i).Name
method := strings.ToUpper(name)
if _, ok := s.methodsMap[method]; !ok {
continue
}
key := name + ":" + pattern
m[key] = &handlerItem {
ctype : v.Elem().Type(),
fname : name,
faddr : nil,
}
}
return s.bindHandlerByMap(m)
}

View File

@ -0,0 +1,113 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 服务注册.
package ghttp
import (
"errors"
"strings"
"reflect"
)
// 绑定控制器控制器需要实现gmvc.Controller接口
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
func (s *Server)BindController(pattern string, c Controller, methods...string) error {
if len(methods) > 0 {
return s.BindControllerMethod(pattern, c, strings.Join(methods, ","))
}
// 遍历控制器获取方法列表并构造成uri
m := make(handlerMap)
v := reflect.ValueOf(c)
t := v.Type()
sname := t.Elem().Name()
for i := 0; i < v.NumMethod(); i++ {
mname := t.Method(i).Name
if mname == "Init" || mname == "Shut" || mname == "Exit" {
continue
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem {
ctype : v.Elem().Type(),
fname : mname,
faddr : nil,
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : v.Elem().Type(),
fname : mname,
faddr : nil,
}
}
}
return s.bindHandlerByMap(m)
}
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
// 第三个参数methods支持多个方法注册多个方法以英文“,”号分隔,不区分大小写
func (s *Server)BindControllerMethod(pattern string, c Controller, methods string) error {
m := make(handlerMap)
v := reflect.ValueOf(c)
e := v.Type().Elem()
t := v.Elem().Type()
sname := e.Name()
for _, method := range strings.Split(methods, ",") {
mname := strings.TrimSpace(method)
if !v.MethodByName(mname).IsValid() {
return errors.New("invalid method name:" + mname)
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem {
ctype : t,
fname : mname,
faddr : nil,
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : t,
fname : mname,
faddr : nil,
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定控制器(RESTFul)控制器需要实现gmvc.Controller接口
// 方法会识别HTTP方法并做REST绑定处理例如Post方法会绑定到HTTP POST的方法请求处理Delete方法会绑定到HTTP DELETE的方法请求处理
// 因此只会绑定HTTP Method对应的方法其他方法不会自动注册绑定
// 这种方式绑定的控制器每一次请求都会初始化一个新的控制器对象进行处理,对应不同的请求会话
func (s *Server)BindControllerRest(pattern string, c Controller) error {
// 遍历控制器获取方法列表并构造成uri
m := make(handlerMap)
v := reflect.ValueOf(c)
t := v.Type()
// 如果存在与HttpMethod对应名字的方法那么绑定这些方法
for i := 0; i < v.NumMethod(); i++ {
name := t.Method(i).Name
method := strings.ToUpper(name)
if _, ok := s.methodsMap[method]; !ok {
continue
}
key := name + ":" + pattern
m[key] = &handlerItem {
ctype : v.Elem().Type(),
fname : name,
faddr : nil,
}
}
return s.bindHandlerByMap(m)
}

View File

@ -0,0 +1,80 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 服务注册.
package ghttp
import (
"errors"
"strings"
"gitee.com/johng/gf/g/util/gstr"
)
// 注意该方法是直接绑定函数的内存地址,执行的时候直接执行该方法,不会存在初始化新的控制器逻辑
func (s *Server)BindHandler(pattern string, handler HandlerFunc) error {
return s.bindHandlerItem(pattern, &handlerItem{
ctype : nil,
fname : "",
faddr : handler,
})
}
// 绑定URI到操作函数/方法
// pattern的格式形如/user/list, put:/user, delete:/user, post:/user@johng.cn
// 支持RESTful的请求格式具体业务逻辑由绑定的处理方法来执行
func (s *Server)bindHandlerItem(pattern string, item *handlerItem) error {
if s.status == 1 {
return errors.New("server handlers cannot be changed while running")
}
return s.setHandler(pattern, item)
}
// 通过映射数组绑定URI到操作函数/方法
func (s *Server)bindHandlerByMap(m handlerMap) error {
for p, h := range m {
if err := s.bindHandlerItem(p, h); err != nil {
return err
}
}
return nil
}
// 将内置的名称按照设定的规则合并到pattern中内置名称按照{.xxx}规则命名。
// 规则1pattern中的URI包含{.struct}关键字,则替换该关键字为结构体名称;
// 规则1pattern中的URI包含{.method}关键字,则替换该关键字为方法名称;
// 规则2如果不满足规则1那么直接将防发明附加到pattern中的URI后面
func (s *Server) mergeBuildInNameToPattern(pattern string, structName, methodName string) string {
structName = s.nameToUrlPart(structName)
methodName = s.nameToUrlPart(methodName)
pattern = strings.Replace(pattern, "{.struct}", structName, -1)
if strings.Index(pattern, "{.method}") != -1 {
return strings.Replace(pattern, "{.method}", methodName, -1)
}
// 检测域名后缀
array := strings.Split(pattern, "@")
// 分离URI(其实可能包含HTTP Method)
uri := array[0]
uri = strings.TrimRight(uri, "/") + "/" + methodName
// 加上指定域名后缀
if len(array) > 1 {
return uri + "@" + array[1]
}
return uri
}
// 将给定的名称转换为URL规范格式。
// 规范1: 全部转换为小写;
// 规范2: 方法名中间存在大写字母转换为小写URI地址以“-”号链接每个单词;
func (s *Server) nameToUrlPart(name string) string {
part := ""
for i := 0; i < len(name); i++ {
if i > 0 && gstr.IsLetterUpper(name[i]) {
part += "-"
}
part += string(name[i])
}
return strings.ToLower(part)
}

View File

@ -0,0 +1,105 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 服务注册.
package ghttp
import (
"errors"
"strings"
"reflect"
)
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
func (s *Server)BindObject(pattern string, obj interface{}, methods...string) error {
if len(methods) > 0 {
return s.BindObjectMethod(pattern, obj, strings.Join(methods, ","))
}
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
sname := t.Elem().Name()
for i := 0; i < v.NumMethod(); i++ {
method := t.Method(i).Name
key := s.mergeBuildInNameToPattern(pattern, sname, method)
m[key] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(method, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 第三个参数methods支持多个方法注册多个方法以英文“,”号分隔,区分大小写
func (s *Server)BindObjectMethod(pattern string, obj interface{}, methods string) error {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
sname := t.Elem().Name()
for _, method := range strings.Split(methods, ",") {
mname := strings.TrimSpace(method)
fval := v.MethodByName(mname)
if !fval.IsValid() {
return errors.New("invalid method name:" + mname)
}
key := s.mergeBuildInNameToPattern(pattern, sname, mname)
m[key] = &handlerItem{
ctype : nil,
fname : "",
faddr : fval.Interface().(func(*Request)),
}
// 如果方法中带有Index方法那么额外自动增加一个路由规则匹配主URI
if strings.EqualFold(mname, "Index") {
p := key
if strings.EqualFold(p[len(p) - 6:], "/index") {
p = p[0 : len(p) - 6]
}
m[p] = &handlerItem {
ctype : nil,
fname : "",
faddr : fval.Interface().(func(*Request)),
}
}
}
return s.bindHandlerByMap(m)
}
// 绑定对象到URI请求处理中会自动识别方法名称并附加到对应的URI地址后面
// 需要注意对象方法的定义必须按照ghttp.HandlerFunc来定义
func (s *Server)BindObjectRest(pattern string, obj interface{}) error {
m := make(handlerMap)
v := reflect.ValueOf(obj)
t := v.Type()
for i := 0; i < v.NumMethod(); i++ {
name := t.Method(i).Name
method := strings.ToUpper(name)
if _, ok := s.methodsMap[method]; !ok {
continue
}
key := name + ":" + pattern
m[key] = &handlerItem {
ctype : nil,
fname : "",
faddr : v.Method(i).Interface().(func(*Request)),
}
}
return s.bindHandlerByMap(m)
}

View File

@ -13,12 +13,17 @@ import (
"encoding/json"
"gitee.com/johng/gf/g/util/gstr"
"gitee.com/johng/gf/g/util/gconv"
"bytes"
)
// 格式化打印变量(类似于PHP-vardump)
func Dump(i interface{}) {
if b, err := json.MarshalIndent(i, "", "\t"); err == nil {
fmt.Println(string(b))
buffer := &bytes.Buffer{}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", "\t")
if err := encoder.Encode(i); err == nil {
fmt.Println(buffer.String())
} else {
fmt.Errorf("%s\n", err.Error())
}

View File

@ -13,10 +13,6 @@ func init() {
g.Server().BindController("/{.struct}/{.method}", &Order{})
}
func (o *Order) Index() {
o.Response.Write("Order Index")
}
func (o *Order) List() {
o.Response.Write("Order List")
o.Response.Write("List")
}

View File

@ -1,27 +1,27 @@
package demo
import (
"gitee.com/johng/gf/g/net/ghttp"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/frame/gmvc"
)
type ControllerMethod struct {
type Method struct {
gmvc.Controller
}
func init() {
ghttp.GetServer().BindControllerMethod("/method", &ControllerMethod{}, "Name, Age")
g.Server().BindControllerMethod("/method", &Method{}, "Name, Age")
}
func (c *ControllerMethod) Name() {
func (c *Method) Name() {
c.Response.Write("John")
}
func (c *ControllerMethod) Age() {
func (c *Method) Age() {
c.Response.Write("18")
}
func (c *ControllerMethod) Info() {
func (c *Method) Info() {
c.Response.Write("Info")
}

View File

@ -1,38 +1,35 @@
package demo
import (
"gitee.com/johng/gf/g/net/ghttp"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/frame/gmvc"
)
// 测试控制器
type ControllerRest struct {
type Rest struct {
gmvc.Controller
}
// 初始化控制器对象并绑定操作到Web Server
func init() {
// 控制器公开方法中与HTTP Method方法同名的方法将会自动绑定映射
ghttp.GetServer().BindControllerRest("/john", &ControllerRest{})
g.Server().BindControllerRest("/rest", &Rest{})
}
// RESTFul - GET
func (c *ControllerRest) Get() {
func (c *Rest) Get() {
c.Response.Write("RESTFul HTTP Method GET")
}
// RESTFul - POST
func (c *ControllerRest) Post() {
func (c *Rest) Post() {
c.Response.Write("RESTFul HTTP Method POST")
}
// RESTFul - DELETE
func (c *ControllerRest) Delete() {
func (c *Rest) Delete() {
c.Response.Write("RESTFul HTTP Method DELETE")
}
// 该方法无法映射,将会无法访问到
func (c *ControllerRest) Hello() {
func (c *Rest) Hello() {
c.Response.Write("Hello")
}

View File

@ -1,43 +1,33 @@
package demo
import (
"gitee.com/johng/gf/g/net/ghttp"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/frame/gmvc"
)
// 定义业务相关的控制器对象,
// 建议命名规范中控制器统一使用Controller前缀后期代码维护时便于区分
type ControllerUser struct {
type User struct {
gmvc.Controller
}
// 初始化控制器对象并绑定操作到Web Server
func init() {
// 绑定控制器到指定URI所有控制器的公开方法将会映射到指定URI末尾
// 例如该方法执行后,查看效果可访问:
// http://127.0.0.1:8199/user/name
// http://127.0.0.1:8199/user/age
// http://127.0.0.1:8199/user/true-name
ghttp.GetServer().BindController("/user", &ControllerUser{})
s := g.Server()
s.BindController("/user", new(User))
s.BindController("/user/{.method}/{uid}", new(User), "Info")
s.BindController("/user/{.method}/{page}.html", new(User), "List")
}
// 定义操作逻辑 - 展示姓名
func (c *ControllerUser) Name() {
c.Response.Write("John")
func (u *User) Index() {
u.Response.Write("User")
}
// 定义操作逻辑 - 展示年龄
func (c *ControllerUser) Age() {
c.Response.Write("18")
func (u *User) Info() {
u.Response.Write("Info - Uid: ", u.Request.Get("uid"))
}
// 定义操作逻辑 - 展示方法名称如果带多个单词,路由控制器使用英文连接符号"-"进行拼接
func (c *ControllerUser) TrueName() {
c.View.Assigns(map[string]interface{}{
})
c.Response.Write("John Smith")
func (u *User) List() {
u.Response.Write("List - Page: ", u.Request.Get("page"))
}

View File

@ -10,14 +10,14 @@ func main() {
s := g.Server()
// 多事件回调示例事件1
pattern1 := "/:name/info/{uid}"
pattern1 := "/:name/info"
s.BindHookHandlerByMap(pattern1, map[string]ghttp.HandlerFunc {
"BeforeServe" : func(r *ghttp.Request) {
fmt.Println("打印到Server端终端")
r.SetQuery("uid", "1000")
},
})
s.BindHandler(pattern1, func(r *ghttp.Request) {
r.Response.Write("用户:", r.Get("name"), ", uid:", r.Get("uid"))
r.Response.Write("用户:", r.Get("name"), ", uid:", r.GetQueryString("uid"))
})
// 多事件回调示例事件2