You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将json.RawMessage反序列化为protobuf.Any类型列表?

解决json.RawMessage反序列化为protobuf repeated Any类型的问题

核心原因

google.protobuf.Any的JSON序列化有特定格式要求,必须包含@type字段指定对应proto消息的类型URL,标准库json.Unmarshal无法自动识别并完成Any类型的包装,导致列表为空。

可行解决方案

方案1:借助临时结构体手动解析(适配非标准JSON格式)

如果你的JSON数据未严格遵循protobuf Any的规范(比如缺少@type),可以通过临时结构体先解析数据,再手动包装为Any类型:

  1. 定义匹配JSON结构的临时结构体:
type TempAnyItem struct {
    TypeURL string          `json:"@type"` // 若JSON无此字段,需手动指定对应类型
    Value   json.RawMessage `json:"value"`
}
  1. 解析json.RawMessage到临时切片,再逐个转换为Any类型:
// raw 是从数据库获取的json.RawMessage
var tempItems []TempAnyItem
if err := json.Unmarshal([]byte(raw), &tempItems); err != nil {
    // 处理解析错误
}

// 目标protobuf结构体,对应定义:repeated google.protobuf.Any list = 1;
target := &YourProtoStruct{}

for _, item := range tempItems {
    // 根据TypeURL创建对应的具体proto消息实例
    var concreteMsg proto.Message
    switch item.TypeURL {
    case "type.googleapis.com/your.package.User":
        concreteMsg = &User{}
    case "type.googleapis.com/your.package.Order":
        concreteMsg = &Order{}
    // 补充其他自定义proto类型分支
    default:
        // 跳过未知类型或处理错误
        continue
    }

    // 反序列化Value到具体消息
    if err := json.Unmarshal(item.Value, concreteMsg); err != nil {
        continue
    }

    // 包装为google.protobuf.Any
    anyMsg, err := anypb.New(concreteMsg)
    if err != nil {
        continue
    }

    target.List = append(target.List, anyMsg)
}

方案2:使用protojson直接解析(适配标准protobuf JSON格式)

如果你的JSON数据严格遵循protobuf的JSON规范(每个元素都包含@type字段),可以直接使用官方的protojson包完成反序列化:

import "google.golang.org/protobuf/encoding/protojson"

// raw 是从数据库获取的json.RawMessage
target := &YourProtoStruct{}
if err := protojson.Unmarshal([]byte(raw), target); err != nil {
    // 处理解析错误
}

关键注意事项

  • 必须确保JSON数据中每个元素的@type字段值正确,格式为type.googleapis.com/你的proto包名.消息类型名
  • 如果JSON数据原本没有@type字段,需要补充该字段,或者在代码中手动指定每个元素对应的具体proto类型,否则无法完成Any类型的反序列化

内容的提问来源于stack exchange,提问作者Mido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:45:57