起因:从MongoDB中获取的时间戳字段在转换成JSON时不符合需求。需要对这个字段定制一下,转换成需要的字符串。
解决方案:
- 最直接的方案就是,对让对应的
struct
实现MarshalJSON
这个方法,自己生成整个JSON字符串, 碰到需要定制的字段,再自行更改。
示例代码如下:Code From
func (this Stuff) MarshalJSON() ([]byte, error) {
buffer := bytes.NewBufferString("{")
length := len(this)
count := 0
for key, value := range this {
jsonValue, err := json.Marshal(value)
if err != nil {
return nil, err
}
buffer.WriteString(fmt.Sprintf("\"%d\":%s", key, string(jsonValue)))
count++
if count < length {
buffer.WriteString(",")
}
}
buffer.WriteString("}")
return buffer.Bytes(), nil
}
- 还有一种方法就是使用辅助
struct
,这样写起来可能比上面的轻松一些。
示例代码如下:Code From
type MyUser struct {
ID int64 `json:"id"`
Name string `json:"name"`
LastSeen time.Time `json:"lastSeen"`
}
func (u *MyUser) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ID int64 `json:"id"`
Name string `json:"name"`
LastSeen int64 `json:"lastSeen"`
}{
ID: u.ID,
Name: u.Name,
LastSeen: u.LastSeen.Unix(),
})
}
- 不过如果字段很多时候,就可能要写很长,但我们只需要更改某些字段。那么可以使用别名
struct
,写出更简短的代码。为什么要为struct
起个别名呢?因为如果直接使用原来的struct
,那么辅助的struct
也会继承原来的MarshalJSON方法,这样就成为一个无限循环了。
示例代码如下:Code From
type MyUser struct {
ID int64 `json:"id"`
Name string `json:"name"`
LastSeen time.Time `json:"lastSeen"`
}
func (u *MyUser) MarshalJSON() ([]byte, error) {
type Alias MyUser
return json.Marshal(&struct {
LastSeen int64 `json:"lastSeen"`
*Alias
}{
LastSeen: u.LastSeen.Unix(),
Alias: (*Alias)(u),
})
}
注意??
MarshalJSON
这个方法返回的是[]byte
,所以如果想打印出来或者使用字符串,需要进行转换string(result)
,否则就会出现链接中的问题