Go语言中PasswordHash结构体JSON序列化异常问题求助
Go json.Marshal时自定义类型MarshalJSON未触发的问题排查
下面是几种最可能导致你遇到的PasswordHash字段序列化后输出{}的原因,附代码示例和修复方案:
1. 仅为指针类型实现了MarshalJSON
json包序列化值类型字段时,只会调用值类型的MarshalJSON方法,如果你只给*PasswordHash实现了方法,值类型字段不会触发该逻辑:
// 错误示例:仅指针类型有MarshalJSON type PasswordHash struct { Hash string } func (p *PasswordHash) MarshalJSON() ([]byte, error) { return json.Marshal(p.Hash) } type User struct { Password PasswordHash // 值类型字段,无法触发指针的MarshalJSON }
修复:给值类型实现MarshalJSON:
func (p PasswordHash) MarshalJSON() ([]byte, error) { return json.Marshal(p.Hash) }
2. 结构体字段未导出
Go的json包只会处理首字母大写的导出字段,不管是User里的Password字段,还是PasswordHash内部的存储字段,小写都会被忽略:
// 错误示例:字段未导出 type User struct { password PasswordHash // 小写字段,json包直接跳过 } type PasswordHash struct { hash string // 小写内部字段,即使方法正确也拿不到值 }
修复:将需要序列化的字段改为首字母大写:
type User struct { Password PasswordHash } type PasswordHash struct { Hash string }
3. MarshalJSON方法内部逻辑错误
如果方法里不小心递归序列化了自身,会导致输出空对象:
// 错误示例:递归序列化 func (p PasswordHash) MarshalJSON() ([]byte, error) { return json.Marshal(p) // 这里会再次调用MarshalJSON,最终输出{} }
修复:明确序列化目标字段(比如内部的Hash字符串):
func (p PasswordHash) MarshalJSON() ([]byte, error) { return json.Marshal(p.Hash) }
4. 错误的json标签
如果User的Password字段加了json:"-"会直接忽略字段,或者omitempty导致零值时被跳过:
// 错误示例:标签导致字段被忽略 type User struct { Password PasswordHash `json:"-"` // 直接排除该字段 }
修复:移除错误标签,或者根据需求调整:
type User struct { Password PasswordHash `json:"password"` }
内容的提问来源于stack exchange,提问作者Sicet7
相关产品推荐
相关产品推荐

