【问题标题】:json.Unmarshal and "push" to array of structsjson.Unmarshal 和“推送”到结构数组
【发布时间】:2021-10-08 10:04:45
【问题描述】:

我的任务是从 AWS MSK(在 AWS lambda 中)读取记录并准备某种有效负载以将其发送到 Facebook。来自 AWS MSK 的记录是 base64 编码的,但是一旦我解码它们,我就会得到 JSON 字符串。现在我不明白json.Unmarshal(decodedParams) 是如何转换为结构数组的&jsonPayload.Data

type Payload struct {
    Data Data `json:"data,required"`
}

type Data []struct{
    Event             string         `json:"event_name,required"`
    EventTime         int            `json:"event_time,required"`
    EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
    EventActionSource string         `json:"action_source,omitempty,required"`
    EventId           int            `json:"event_id,required"`
    UserData          UserDataType   `json:"user_data,required"`
    CustomData        CustomDataType `json:"custom_data,omitempty"`
}

type CustomDataType struct {
    SearchString     string      `json:"search_string,omitempty"`
    Value            json.Number `json:"value,omitempty"`
    Currency         string      `json:"currency,omitempty"`
}
type UserDataType struct {
    IpAddress string `json:"client_ip_address,omitempty,required"`
    UserAgent string `json:"client_user_agent,omitempty,required"`
}

// ProcessEvent function Using AWS Lambda computed event
func ProcessEvent(event events.KafkaEvent) {

    jsonPayload := Payload{}

    for _, mapper := range event.Records {

        for _, record := range mapper {

            // Base64 decode string from MSK Kafka
            decodedParams, err := base64.StdEncoding.DecodeString(record.Value)
            if err != nil {
                log.Fatal("Error decoding fb event params: ", err)
            }

            // json.Unmarshal and push to Data []structs???
            unmErr := json.Unmarshal(decodedParams, &jsonPayload.Data)
            if unmErr != nil {
                fmt.Println("UNMARSHAL ERROR")
                fmt.Println(unmErr)
            }
        }
    }
}

func main() {
    lambda.Start(ProcessEvent)
}

payload的最终结果应该和这个类似

{
   "data":[
      {
         "event_name":"Purchase",
         "event_time":1627975460,
         "action_source":"email",
         "user_data":{
            "em":[
               "7b17fb0bd173f625b58636fb796407c22b3d16fc78302d79f0fd30c2fc2fc068"
            ],
            "ph":[
               null
            ]
         },
         "custom_data":{
            "currency":"USD",
            "value":"142.52"
         }
      },
      {
         "event_name":"PageView",
         "event_time":1627975460,
         "action_source":"email"
      }
   ]
}

目前我遇到了错误

json: cannot unmarshal object into Go value of type main.Data

由于我对 GO 还很陌生,我想知道我是否走在正确的道路上以及如何将解码的 json 字符串推送到 Data []struct 中?如果您需要任何其他信息,请告诉我,我会提供。谢谢!

【问题讨论】:

  • 嗯,在我看来,您走在正确的道路上。你遇到了什么问题?你收到错误了吗? decodedParams json 是否匹配 Data 类型的结构?
  • 抱歉,目前我收到错误 json: cannot unmarshal object into Go value of type main.Data
  • 这意味着decodeParams 包含一个json 对象并且不是一个json 数组。但是您已将 Data 定义为 []struct,因此 json.Unmarshal 需要一个 json 数组而不是对象。将Data []struct{... 更改为Data struct{...,就解组而言,您应该没问题。
  • 如果decodedParams有时可以包含一个json对象,有时可以包含一个json数组,你可以做的是检查第一个和最后一个字节,如果是{,}而不是[,] 那么你知道它是一个对象而不是一个数组,你可以通过添加 [ 并添加 ] 来“规范化”json。
  • 还请注意,如果您只需将 decodedParams 发送到 facebook,那么您不需要解组它,您可以使用 json.RawMessage 按原样发送它类型。例如type Payload struct { Data json.RawMessage } 然后,解码后你会做jsonPayload.Data = json.RawMessage(decodedParams)

标签: amazon-web-services go aws-lambda aws-msk


【解决方案1】:

event.Records 的每一次迭代都可能覆盖你拥有的任何东西,更多的尝试将.Data 想象为[]data 的一部分

type data struct {
    Event             string         `json:"event_name,required"`
    EventTime         int            `json:"event_time,required"`
    EventSourceUrl    string         `json:"event_source_url,omitempty,required"`
    EventActionSource string         `json:"action_source,omitempty,required"`
    EventId           int            `json:"event_id,required"`
    UserData          UserDataType   `json:"user_data,required"`
    CustomData        CustomDataType `json:"custom_data,omitempty"`
}

type Data []data

因此,您将拥有 unmarshal 并推送到 Data 切片小 data 结构的代码,类似于此。

var d data
unmErr := json.Unmarshal(decodedParams, &d)
if unmErr != nil {
    fmt.Println("UNMARSHAL ERROR")
    fmt.Println(unmErr)
}

jsonPayload.Data = append(jsonPayload.Data, d) 

【讨论】:

    猜你喜欢
    • 2015-03-29
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 2022-06-10
    • 2020-09-05
    相关资源
    最近更新 更多