我目前正在为golang中的博客开发JSON API,并且遇到试图处理博客帖子的序列化和反序列化的障碍。我希望我的帖子包含可能包含许多内容(如正常段落,图片,引号等)的帖子部分数组。我使用蒙戈存储(与惊人的mgo library),我要保存这样的帖子:Go中的接口的自定义JSON序列化和反序列化
{
"title": "Blog post",
"sections": [
{
"type": "text",
"content": { "en": "English content", "de": "Deutscher Inhalt" }
},
{
"type": "image",
"content": "https://dummyimage.com/100x100"
},
...more sections
],
...other fields
}
我已经尝试了几种解决方案中去实现这一点,并没有真的似乎是“正确的方法”来做到这一点:
- 不关心内容
这似乎是显而易见的解决方案,只是用一个简单的结构:
type PostSection struct{
Type string
Content interface{}
}
这样,我可以通过任何前端POSTS并保存它。但是,操纵数据或验证数据变得不可能,所以这不是一个好的解决方案。
- 使用自定义接口系列化
- 编写自定义序列。这导致超级丑陋的代码,因为我只真正需要自定义代码的单一领域,所以我经过休息,使反序列化类似于此:
p.ID = decoded.ID p.Author = decoded.Author p.Title = decoded.Title p.Intro = decoded.Intro p.Slug = decoded.Slug p.TitleImage = decoded.TitleImage p.Images = decoded.Images ...more fields...
,然后,像切片解码这样的:
sections := make([]PostSection, len(decoded.Sections)) for i, s := range decoded.Sections { if s["type"] == "text" { content := s["content"].(map[string]interface{}) langs := make(PostText, len(content)) for lang, langContent := range content { langString := langContent.(string) langs[lang] = langString } sections[i] = &langs } else if s["type"] == "image" { content := s["content"].(string) contentString := PostImage(content) sections[i] = &contentString } } p.Sections = sections
这是一大堆的代码,我将不得不使用每次我想包括以另一种形式在其他地方(例如在通讯)PostSections时间,它不觉得自己是地道的Go代码通过一次远射。此外,没有错误处理格式错误的部分 - 他们只是造成这样的恐慌。
有没有一个干净的解决这个问题?
我发现this article有关golang串行接口。这似乎在第一个伟大的,因为我有一个这样的接口:
type PostSection interface{
Type() string
Content() interface{}
}
,然后实现所有类型如下:
type PostImage string
func (p *PostImage) Type() string {
return "image"
}
func (p *PostImage) Content() interface{} {
return p
}
理想情况下,这将一直是,贯彻MarshalJSON
后和UnmarshalJSON
所有我的类型,它直接在PostSection对象上使用json.Marshal时工作正常。
然而,序列化或反序列化含有PostSection
秒的阵列的整个Post对象时,我的自定义代码只是被忽略并且PostSections只想被视为串行化时底层对象(在实施例中string
或map[string]string
),或者在反序列化时导致空对象。
-
对于整个邮政结构
整个Post对象所以,我目前使用,但希望改变溶液是自定义序列
#2,'当对包含PostSections数组的整个Post对象进行序列化或反序列化时,我的自定义代码没有被使用,并且我会得到错误。什么错误?你是否为Post对象本身实现了'MarshalJSON'和'UnmarshalJSON'? – RayfenWindspear
对不起,但似乎我记得那是错的。我只是试了一遍,错误只出现在试图从mgo反序列化时,因为它找不到PostSection接口的SetBSON方法。至于你的第二个问题,我在#3中谈论这个问题。 – happens