赞
踩
最近做一个需求,各种业务消息都会往我的消息队列中写各种类型的数据,服务端需要接受各种不同的参数然后转换为本地数据结构,Go语言不确定上游传过来的数值是什么类型,然后又下面四种解决方案。
func (MissionEventHandler) Handle(ctx context.Context, message *kafka.Message) error { var raw map[string]interface{} err := json.Unmarshal(message.Value, &raw) if err != nil { // Handle error return err } switch raw["event"] { case mission.MISSION_EVENT_PAY_SUCCESS: uid, ok1 := raw["uid"].(string) time, ok2 := raw["time"].(string) num, ok3 := raw["num"].(float64) // JSON numbers are float64 by default if !ok1 || !ok2 || !ok3 { // Handle type assertion error return errors.New("type assertion failed") } // Handle the event // ... // Add cases for other event types default: // Handle unknown event } return nil }
type Event struct { Event string `json:"event"` } type PaySuccessEvent struct { Event UID string `json:"uid"` Time string `json:"time"` Num int `json:"num"` } // ... Define other specific event structs func (MissionEventHandler) Handle(ctx context.Context, message *kafka.Message) error { var baseEvent Event err := json.Unmarshal(message.Value, &baseEvent) if err != nil { // Handle error return err } switch baseEvent.Event { case mission.MISSION_EVENT_PAY_SUCCESS: var paySuccessEvent PaySuccessEvent err := json.Unmarshal(message.Value, &paySuccessEvent) if err != nil { // Handle error return err } // Handle the event // ... // Add cases for other event types default: // Handle unknown event } return nil }
json.RawMessage
type GenericEvent struct { Event string `json:"event"` Data json.RawMessage `json:"data"` } func (MissionEventHandler) Handle(ctx context.Context, message *kafka.Message) error { var genericEvent GenericEvent err := json.Unmarshal(message.Value, &genericEvent) if err != nil { // Handle error return err } switch genericEvent.Event { case mission.MISSION_EVENT_PAY_SUCCESS: var paySuccessEvent PaySuccessEvent err := json.Unmarshal(genericEvent.Data, &paySuccessEvent) if err != nil { // Handle error return err } // Handle the event // ... // Add cases for other event types default: // Handle unknown event } return nil }
map[string]interface{}
和反射import ( "reflect" "encoding/json" ) func (MissionEventHandler) Handle(ctx context.Context, message *kafka.Message) error { var raw map[string]interface{} err := json.Unmarshal(message.Value, &raw) if err != nil { // Handle error return err } switch raw["event"] { case mission.MISSION_EVENT_PAY_SUCCESS: paySuccessEvent := reflect.New(reflect.TypeOf(PaySuccessEvent{})).Interface() err := mapstructure.Decode(raw, &paySuccessEvent) if err != nil { // Handle error return err } // Handle the event // ... // Add cases for other event types default: // Handle unknown event } return nil }
在第四种方法中,使用了mapstructure
库,可以将通用的map值解码到相应的结构体中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。