使用自定义MarshalJSON更改结构中的JSON标签 [英] Changing JSON tags in struct with custom MarshalJSON
问题描述
我们得到一些JSON输入,将其解组,执行一些工作,然后将其编组并运送到其他地方.我们得到的JSON可能有一个名为"user"的字段.当我们编组回JSON时,我们需要将用户"字段更改为用户名".我们可以通过创建一个具有所有相同字段但具有不同JSON标记的新结构来完成此操作,但这似乎有点麻烦.我以为自定义编组器可以在这里工作,但我有点卡住了.考虑以下代码.
We get some JSON input, unmarshal, perform some work, then marshal and ship off somewhere else. The JSON we get may have a field named "user". When we marshal back to JSON we need to have that field "user" changed to "username". We can do this by creating a new struct with all the same fields, but different JSON tags, but that seemed a bit cumbersome. I thought a custom marshaller would work here, but I'm a bit stuck. Consider the following code.
package main
import (
"encoding/json"
"fmt"
)
type StructA struct {
Username string `json:"user"`
Process string `json:"process"`
}
func main() {
var test1 StructA
err := json.Unmarshal([]byte(`{"user": "user123", "process": "something"}`), &test1)
if err != nil {
fmt.Println(err)
}
// do some work with test1
jsonByte, err := json.Marshal(&test1)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(jsonByte))
}
func (u *StructA) MarshalJSON() ([]byte, error) {
type Alias StructA
return json.Marshal(&struct {
Username string `json:"username"`
*Alias
}{
Username: u.Username,
Alias: (*Alias)(u),
})
}
https://play.golang.org/p/_w0rlQrcgrW
理想情况下,这将允许我将该字段上的JSON标签从用户"更改为用户名".但是,我同时获得了用户名"和用户".
Ideally this would allow me to change the JSON tag on that field from "user" to "username". However, I get both "username" and "user".
{"username":"user123","user":"user123","process":"something"}
我当然可以创建一个全新的结构,以所需的标签镜像StructA,但是我不必复制每个字段,也不必担心使这两个结构保持同步.这不是世界末日,但这似乎不是一个好方法.
I certainly could create an entirely new struct that mirrors StructA with the tags I want, but I don't have to have to copy every single field and worry about keeping those two structs in sync. It's not the end of the world, but it doesn't seem like a good approach.
很明显,我要寻找的最终结果如下:
To be clear, the end result I'm looking for is the following:
{"username":"user123","process":"something"}
我敢肯定,我在这里缺少一些琐碎的事情,但这已经是一个漫长的一周,我们将不胜感激.谢谢!
I'm sure I'm missing something trivial here, but it's been a long week and any assistance would be appreciated. Thanks!
推荐答案
一个选项可能是让一个结构具有不变的值,然后是2个替代结构,它们都包含该结构且仅具有变化的值.然后,您可以将其中一个用于编组,而将第二个用于编组.
One option could be to have one struct with the non-changing values and than 2 alternative structs which both include that struct and have only the changing values. You then use one for unmarshaling and the second one for marshaling.
type StructA struct {
Process string `json:"process"`
...
}
type WithUser struct {
StructA
Username `json:"user"`
}
type WithUsername struct {
StructA
Username `json:"username"`
}
这将需要多个结构,但每个结构都没有重复,并且可以很灵活地包含在其中,而不是将要更改的内容硬编码为自定义编组函数.
This would require multiple structs but no duplication in each one and can be quite flexible in what you include, instead of hard coding what you want to change into a custom marshal function.
这篇关于使用自定义MarshalJSON更改结构中的JSON标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!