我希望能够访问由JSON unmarshal产生的结构字段,但我想使用相同的结构来隐藏字段。
示例:
type MyStruct struct {
GoodField string `json:"goodField"`
SecretField string `json:"secret"`
}
传入的JSON被取消编组,secret
字段可供访问
在服务器响应中使用相同的MyStruct
,但隐藏 secret
字段。
我查看了使用omitempty
和-
代码,但没有工作。
答案 0 :(得分:1)
您使用omitempty
走在正确的轨道上,只需将SecretField
设置为""
即可生效
package main
import (
"fmt"
"encoding/json"
)
type MyStruct struct {
GoodField string `json:"goodField"`
SecretField string `json:"secret,omitempty"`
}
func main() {
data := MyStruct{}
s := `{"goodField": "xxx", "secret": "yyy"}`
json.Unmarshal([]byte(s), &data);
fmt.Println(data.GoodField, data.SecretField);
data.SecretField = ""
response, _ := json.Marshal(data)
fmt.Println(string(response))
}
答案 1 :(得分:0)
If you can't, or don't want, to set the field to empty, you can accomplish this with a custom marshaler, as well:
type MyStruct struct {
GoodField string `json:"goodField"`
SecretField string `json:"secret"`
}
func (ms *MyStruct) MarshalJSON() ([]byte, error) {
type MyStructWithoutSecretFields struct {
GoodField string `json:"goodField"`
}
noSecrets := MyStructWithoutSecretFields{
GoodField: ms.GoodField,
}
return json.Marshal(noSecrets)
}
答案 2 :(得分:0)
此外,如果您只需要从此软件包访问此字段(这可以帮助您完全控制对它的访问),您可以使用第一个小写字母将其设为 unexported 。将此结构用于除编组/解组之外的所有操作。
type MyStruct struct {
GoodField string `json:"goodField"`
secretField string `json:"secret"`
}
再制作一个仅用于编组的结构。
答案 3 :(得分:0)
总的来说,我认为最好的模式是使用单独的请求和响应类型,而不是仅仅为了防止数据封送而变异数据。那是一种侵入性和破坏性的方法,其副作用可能会咬你。与Go谚语“有点重复比一点依赖要好”相一致,您最好只是分离这些关注点,而不是尝试让一种类型承担双重职责。
但是,如果需要,您可以尝试使用结构嵌入将字段声明DRY干燥。通过结合使用omitempty
和-
json
标签,可以得到所需的结果:
type payload struct {
A string `json:"a"`
B string `json:"b,omitempty"`
}
type request struct {
payload
}
type response struct {
payload
B string `json:"-"`
}
以下是上述worked example。
要注意的并不是没有问题,这里有两个名为B
的字段,而不是一个。如果您像我的示例中那样仅使用点运算符字段访问,则效果很好。如果使用struct文字,则必须注意不要将值放在错误的位置。为这些类型编写构造函数,将这种关注集中在一个地方并正确解决,可能是一个好主意。