1 Star 1 Fork 2

kristas/booting-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
controller_processor.go 3.52 KB
一键复制 编辑 原始数据 按行查看 历史
kristas 提交于 2021-04-19 23:12 . refactor: flyway
package web_processor
import (
"fmt"
"gitee.com/kristas/booting-go/framework/announce"
"gitee.com/kristas/booting-go/framework/common/util/lang"
"gitee.com/kristas/booting-go/framework/common/util/list"
"gitee.com/kristas/booting-go/framework/common/util/reflectx"
. "gitee.com/kristas/booting-go/framework/core/bean"
"gitee.com/kristas/booting-go/framework/web"
"reflect"
)
type ControllerProcessor struct {
}
func (c *ControllerProcessor) Filter(bean Bean) bool {
return reflectx.IsImplement(bean, new(announce.Controller))
}
func (c *ControllerProcessor) Do(bean Bean) {
controller := bean.(announce.Controller)
doHandler(controller)
}
var (
Path = "path"
Query = "query"
Body = "body"
Header = "header"
Form = "form"
Multipart = "multipart"
Context = "context"
Request = "request"
Response = "response"
App = "app"
)
var (
methodDefine = list.NewList("GET", "POST", "PUT", "PATCH", "DELETE")
sourceDefine = list.NewList(Path, Query, Body, Form, Header, Multipart, Context, Request, Response, App)
defaultSource = Query
Handler WebHandler
)
type Param struct {
Name string
Source string
Type reflect.Type
}
func (r Param) String() string {
return fmt.Sprintf("Param:{name:%s, source:%s, type: %s}", r.Name, r.Source, r.Type.String())
}
type WebHandler func(httpMethod, url string, params []Param, funcType reflect.Method, funcValue reflect.Value)
func doHandler(controller announce.Controller) {
typ := reflect.TypeOf(controller)
val := reflect.ValueOf(controller)
reflectx.WalkStructField(controller, func(field reflect.StructField, value reflect.Value) {
if isRouteAPI(field) {
if method, ok := typ.MethodByName(methodName(field)); ok {
if Handler == nil {
panic("need a web handler")
} else {
httpMethod, url := findHttpMethodAndUrl(field)
paramMap := buildParam(field.Tag.Get("param"), method.Type)
url = controller.Controller() + url
methodVal := val.MethodByName(methodName(field))
Handler(httpMethod, url, paramMap, method, methodVal)
}
}
}
}, false)
}
func isRouteAPI(field reflect.StructField) bool {
var api web.API
if field.Type == reflect.TypeOf(api) {
return true
}
return false
}
func findHttpMethodAndUrl(field reflect.StructField) (string, string) {
method, ok := methodDefine.Find(func(item interface{}) bool {
_, ok := field.Tag.Lookup(item.(string))
return ok
})
if ok {
return method.(string), field.Tag.Get(method.(string))
}
panic("legal url not found in " + field.Name)
}
func buildParam(param string, method reflect.Type) []Param {
var paramQueue = make([]Param, 0)
paramStr := lang.NewString(param).RemovePrefix("[").RemoveSuffix("]").
ReplaceAll(" ,", ",").ReplaceAll(", ", ",")
if paramStr.String() == "" {
return paramQueue
}
paramArr := paramStr.ReplaceAll(" ", ",").Split(",")
params := lang.TransferSliceToSimple(paramArr)
var scope = defaultSource
for i := len(params) - 1; i >= 0; i-- {
e := params[i]
if sourceDefine.Contains(e) {
scope = e
} else {
paramQueue = append(paramQueue, Param{
Name: e,
Source: scope,
})
}
}
reverseParam(paramQueue)
for i := 0; i < method.NumIn()-1; i++ {
in := method.In(i + 1)
paramQueue[i].Type = in
}
return paramQueue
}
func reverseParam(param []Param) {
for i := range param {
if i == len(param)/2 {
break
}
param[i], param[len(param)-1-i] = param[len(param)-1-i], param[i]
}
}
func methodName(field reflect.StructField) string {
method := lang.NewString(field.Name).FirstLetterUpper()
return method.String()
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/kristas/booting-go.git
git@gitee.com:kristas/booting-go.git
kristas
booting-go
booting-go
v1.2.4

搜索帮助

344bd9b3 5694891 D2dac590 5694891