首页 文章

自定义编组到bson和JSON(Golang&mgo)

提问于
浏览
1

我在Golang中有以下类型:

type Base64Data []byte

为了支持将base64编码的字符串解组为此类型,我执行了以下操作:

func (b *Base64Data) UnmarshalJSON(data []byte) error {
    if len(data) == 0 {
        return nil
    }

    content, err := base64.StdEncoding.DecodeString(string(data[1 : len(data)-1]))
    if err != nil {
        return err
    }

    *b = []byte(xml)
    return nil
}

现在我也希望能够使用mgo Golang库将其编组并解组到mongo数据库 . 问题是我已经将文件存储为base64编码的字符串,所以我必须保持这一点 . 我试着做以下事情:

func (b Base64Data) GetBSON() (interface{}, error) {
    return base64.StdEncoding.EncodeToString([]byte(b)), nil
}

func (b *Base64DecodedXml) SetBSON(raw bson.Raw) error {
    var s string
    var err error
    if err = raw.Unmarshal(&s); err != nil {
        return err
    }
    *b, err = base64.StdEncoding.DecodeString(s)
    return err
}

因此,在解组之后,数据已经被解码,所以我需要对其进行编码,并将其作为字符串返回,以便将其作为字符串写入db(反之亦然)为此我实现了bson getter和setter,但是似乎只有吸气剂正常工作

来自base64编码字符串的JSON解组工作,以及将其编组到数据库 . 但似乎根本没有打电话 .

任何人都可以建议我缺少什么,以便我能够正确地保存在内存中解码的数据,但编码的字符串类型?

这是我试图运行的测试:

b := struct {
    Value shared.Base64Data `json:"value" bson:"value"`
}{}
s := `{"value": "PHJvb3Q+aGVsbG88L3Jvb3Q+"}`
require.NoError(t, json.Unmarshal([]byte(s), &b))
t.Logf("%v", string(b.Value))
b4, err := bson.Marshal(b)
require.NoError(t, err)
t.Logf("%v", string(b4))
require.NoError(t, bson.Unmarshal(b4, &b))
t.Logf("%v", string(b.Value))

1 回答

  • 1

    您不能使用bson.Marshal()封送任何值,只能映射 Map 和结构值 .

    如果你想测试它,传递 map ,例如bson.Mbson.Marshal()

    var x = Base64Data{0x01, 0x02, 0x03}
    
    dd, err := bson.Marshal(bson.M{"data": x})
    fmt.Println(string(dd), err)
    

    您的代码按原样运行,并且正如您所希望的那样 . 尝试插入包装器值以验证它:

    c := sess.DB("testdb").C("testcoll")
    
    var x = Base64Data{0x01, 0x02, 0x03}
    if err := c.Insert(bson.M{
        "data": x,
    }); err != nil {
        panic(err)
    }
    

    这将把数据保存为 string ,即Base64编码形式 .

    当然,如果要将其加载回 Base64Data 类型的值,您还需要定义 SetBSON(raw Raw) error 方法(bson.Setter interface) .

相关问题