2

我有一个从 Google PubSub 请求接收数据的端点。根据这个 repo,对象是这样的:

type pushRequest struct {
    Message struct {
        Attributes map[string]string
        Data       []byte
        ID         string `json:"message_id"`
    }
    Subscription string
}

数据字段的格式一致,如下所示:

type Data struct {
    Key  string                 `json:"key"`
    Body string                 `json:"body"`
    Meta map[string]interface{} `json:"meta"`
}

我可以明显地用这样的方式解组 JSON 请求:

f := &pushRequest{}
json.Unmarshal(msg, &f)

剩下的 []bytes 字段。根据文档,我可以做这样的事情来转换为字符串

messages = append(messages, string(f.Message.Data))

这没有帮助,因为我需要它作为一个结构。

我可以再次解组数组:

var m Data
json.Unmarshal(f.Message.Data, &m)

尝试将 pushRequest 结构中的字段类型更改为 Data 但没有成功。空白的...

有没有一种方法可以一次性打开包装?做两次似乎很荒谬。

如果很明显,我就是看不到!

4

2 回答 2

1

这是我的云功能的一个片段,它用作发布/订阅推送端点。关键是您首先必须使用PushRequest结构解码主体。接下来,您可以将消息数据转换为结构。根据文档,其中的Data字段Message是 base-64 编码的字符串,因此您必须先对其进行解码。

type PushRequest struct {
    Message      pubsub.PubsubMessage `json:"message"`
    Subscription string               `json:"subscription"`
}

type Example struct {
    ID string `json:"id" firestore:"id"`
}

func HTTPEndpoint(w http.ResponseWriter, r *http.Request) {
    var pr common.PushRequest
    if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
        log.Fatalf("Could not decode body: %v", err)
        return
    }

    data, err := base64.StdEncoding.DecodeString(pr.Message.Data)
    if err != nil {
        log.Fatalf("Base64: %v", err)
        return
    }

    var example Example
    if err := json.Unmarshal(data, &example); err != nil {
        log.Fatalf("Json: %v", err)
        return
    }

    // Do something useful with the struct
}
于 2021-07-24T01:27:56.590 回答
1
decoder := json.NewDecoder(r.Body)
psmsg := &PushRequest{}
decoderErr := decoder.Decode(&psmsg)

if decoderErr != nil {
    // Error... 
    return
}

data := Data{}
unmarshalErr := json.Unmarshal([]byte(string(psmsg.Message.Data)), &data)

if unmarshalErr != nil {
    // Error...
    return
}
于 2019-03-12T14:29:12.120 回答