优化字段结构定义 + 半成品映射规则解析
This commit is contained in:
parent
bbb9639b09
commit
7b7aee4070
63
define.go
63
define.go
@ -10,14 +10,18 @@ package event
|
||||
import "reflect"
|
||||
|
||||
const (
|
||||
// OutputKeyTag 事件数据输出key的标签
|
||||
OutputKeyTag = "event"
|
||||
// OutEventTag 事件数据输出key的标签
|
||||
OutEventTag = "event"
|
||||
// JsonTag json输出的标签
|
||||
JsonTag = "json"
|
||||
// IgnoreTagValue 不做输出的标签值
|
||||
IgnoreTagValue = "-"
|
||||
// MappingTag 参数映射标签
|
||||
MappingTag = "mapping"
|
||||
// PriorityTag 处理数据时, mapping数据查找的优先级, 默认值 : field
|
||||
PriorityTag = "priority"
|
||||
// OmitemptyTag ...
|
||||
OmitemptyTag = "omitempty"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -33,15 +37,52 @@ const (
|
||||
MappingLocationExtension = "extension"
|
||||
)
|
||||
|
||||
var (
|
||||
mappingLocationList = []string{
|
||||
MappingLocationHeader,
|
||||
MappingLocationParam,
|
||||
MappingLocationResponse,
|
||||
MappingLocationExtension,
|
||||
}
|
||||
)
|
||||
|
||||
// SetMappingLocationList 只持续该默认的查找优先级
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:17 2023/2/1
|
||||
func SetMappingLocationList(locationList []string) {
|
||||
if len(locationList) > 0 {
|
||||
mappingLocationList = locationList
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// PriorityLocation 读取位置优先
|
||||
PriorityLocation = "location"
|
||||
// PriorityField 读取字段优先
|
||||
PriorityField = "field"
|
||||
)
|
||||
|
||||
// MappingRuleItem 规则
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:36 2023/2/1
|
||||
type MappingRuleItem struct {
|
||||
Location string `json:"location"` // 数据所在位置, header-请求头 param-参数获取 response-响应数据获取 extension-扩展数据读取 all-自动按照header/param/response/extension的顺序查询
|
||||
Field string `json:"field"` // 查询的字段名称
|
||||
}
|
||||
|
||||
// MappingRule 数据映射规则
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:24 2023/2/1
|
||||
type MappingRule struct {
|
||||
Location string `json:"location"` // 数据所在位置, header-请求头 param-参数获取 response-响应数据获取 extension-扩展数据读取 all-自动按照header/param/response/extension的顺序查询
|
||||
Field []string `json:"field"` // 查询的字段名称, 列表, 按照优先级诸葛查询
|
||||
Priority string `json:"priority"` // 查找优先级 : location - 位置优先 field - 字段优先
|
||||
RuleList []MappingRuleItem `json:"rule_list"` // 规则列表
|
||||
Priority string `json:"priority"` // 查找优先级 : location - 位置优先 field - 字段优先
|
||||
TargetField string `json:"target_field"` // 目标字段
|
||||
}
|
||||
|
||||
// StructField 结构体字段信息
|
||||
@ -50,9 +91,21 @@ type MappingRule struct {
|
||||
//
|
||||
// Date : 14:35 2023/2/1
|
||||
type StructField struct {
|
||||
Idx int // 字段在结构体的索引
|
||||
Name string // 字段名
|
||||
Type reflect.Kind // 字段类型
|
||||
JsonTag string // json标签
|
||||
EventTag string // 事件标签
|
||||
MappingRule *MappingRule // 数据映射规则
|
||||
}
|
||||
|
||||
// StructInfo 结构体信息
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:17 2023/2/1
|
||||
type StructInfo struct {
|
||||
Flag string // 结构体标识
|
||||
IsStruct bool // 是否为结构体
|
||||
StructFieldList []*StructField // 结构体字段列表
|
||||
}
|
||||
|
126
reflect.go
126
reflect.go
@ -7,12 +7,34 @@
|
||||
// Date : 2023-02-01 14:30
|
||||
package event
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// ReflectTypeInstance 反射实例
|
||||
ReflectTypeInstance *ReflectType
|
||||
)
|
||||
|
||||
func init() {
|
||||
ReflectTypeInstance = &ReflectType{
|
||||
lock: &sync.RWMutex{},
|
||||
cacheTable: make(map[string]*StructInfo),
|
||||
}
|
||||
}
|
||||
|
||||
// ReflectType 反射数据类型
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:31 2023/2/1
|
||||
type ReflectType struct {
|
||||
// 数据锁
|
||||
lock *sync.RWMutex
|
||||
// 反射结果缓存
|
||||
cacheTable map[string]*StructInfo
|
||||
}
|
||||
|
||||
// Do 反射获取数据类型
|
||||
@ -20,6 +42,108 @@ type ReflectType struct {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:34 2023/2/1
|
||||
func (rt *ReflectType) Do(data interface{}) {
|
||||
//
|
||||
// 为特定结构体生成全局唯一的标识, 并进行缓存, 加速反射结果获取
|
||||
func (rt *ReflectType) Do(dataFlag string, data interface{}) *StructInfo {
|
||||
rt.lock.Lock()
|
||||
defer rt.lock.Unlock()
|
||||
if cacheResult, exist := rt.cacheTable[dataFlag]; exist {
|
||||
// 缓存存在, 直接是有缓存结果
|
||||
return cacheResult
|
||||
}
|
||||
|
||||
// 缓存不存在, 解析
|
||||
res := &StructInfo{
|
||||
Flag: dataFlag,
|
||||
IsStruct: false,
|
||||
StructFieldList: make([]*StructField, 0),
|
||||
}
|
||||
reflectType := reflect.TypeOf(data)
|
||||
if reflectType.Kind() == reflect.Ptr {
|
||||
reflectType = reflectType.Elem()
|
||||
}
|
||||
if reflectType.Kind() != reflect.Struct {
|
||||
// 非结构体,无需反射
|
||||
return res
|
||||
}
|
||||
res.IsStruct = true
|
||||
for idx := 0; idx < reflectType.NumField(); idx++ {
|
||||
field := &StructField{
|
||||
Idx: idx,
|
||||
Name: reflectType.Field(idx).Name,
|
||||
Type: reflectType.Field(idx).Type.Kind(),
|
||||
JsonTag: reflectType.Field(idx).Tag.Get(JsonTag),
|
||||
EventTag: reflectType.Field(idx).Tag.Get(OutEventTag),
|
||||
MappingRule: nil,
|
||||
}
|
||||
|
||||
res.StructFieldList = append(res.StructFieldList, field)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// fillTagInfo 填充标签信息
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:11 2023/2/1
|
||||
func (rt *ReflectType) fillTagInfo(field *StructField) {
|
||||
if len(field.JsonTag) == 0 {
|
||||
field.JsonTag = field.Name
|
||||
}
|
||||
|
||||
// jsonTag 去掉 omitempty
|
||||
jsonTagValArr := strings.Split(field.JsonTag, ",")
|
||||
for _, item := range jsonTagValArr {
|
||||
if len(item) > 0 && item != OmitemptyTag {
|
||||
field.JsonTag = item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 没有设置event tag,则和
|
||||
if len(field.EventTag) == 0 {
|
||||
field.EventTag = field.JsonTag
|
||||
}
|
||||
}
|
||||
|
||||
// fillMappingRule 解析参数映射规则
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:14 2023/2/1
|
||||
//
|
||||
// mapping:"user_id:param#user_id|header#id"
|
||||
func (rt *ReflectType) fillMappingRule(field *StructField, inputMappingVal string, inputPriorityVal string) {
|
||||
rule := &MappingRule{
|
||||
RuleList: make([]MappingRuleItem, 0),
|
||||
Priority: "",
|
||||
TargetField: "",
|
||||
}
|
||||
switch inputPriorityVal {
|
||||
case PriorityLocation:
|
||||
rule.Priority = PriorityLocation
|
||||
case PriorityField:
|
||||
rule.Priority = PriorityField
|
||||
default:
|
||||
rule.Priority = PriorityField
|
||||
}
|
||||
if len(inputMappingVal) == 0 {
|
||||
// 没有指定规则, 有默认规则
|
||||
for _, location := range mappingLocationList {
|
||||
rule.RuleList = append(rule.RuleList, MappingRuleItem{
|
||||
Location: location,
|
||||
Field: field.JsonTag,
|
||||
})
|
||||
}
|
||||
field.MappingRule = rule
|
||||
return
|
||||
}
|
||||
mappingArr := strings.Split(inputMappingVal, ",")
|
||||
for _, item := range mappingArr {
|
||||
item = strings.TrimSpace(item)
|
||||
// 要赋值的字段名
|
||||
itemArr := strings.Split(item, ":")
|
||||
rule.TargetField = strings.TrimSpace(itemArr[0])
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user