Go语言JSON反序列化后Filter字段未正确解析,如何解决?
问题分析
你的代码无法正确反序列化Filter字段的核心原因是JSON结构与Go结构体定义不匹配:
- JSON中的
filter是一个扁平对象,键为带前缀的字符串"permission.IsAdmin"; - 你定义的
FilterCondition结构体期望permission作为嵌套键对应一个map,两者结构完全不兼容,导致反序列化后Permissions为空map。
同时你需要将JSON中静态的true替换为动态权限判断逻辑(如permissions.Role == "admin")。
解决方案
通过给FilterCondition实现自定义的json.Unmarshaler接口,手动解析带前缀的权限键,并替换为动态判断逻辑:
package main import ( "encoding/json" "fmt" "os" "strings" ) // 模拟权限上下文,实际可从请求、配置等地方获取 var permissions = struct { Role string }{ Role: "admin", // 示例角色,可按需修改 } type FilterCondition struct { Permissions map[string]bool } // 自定义JSON反序列化逻辑,处理"permission.Xxx"格式的键 func (fc *FilterCondition) UnmarshalJSON(data []byte) error { // 先将JSON反序列化为临时map tempMap := make(map[string]bool) if err := json.Unmarshal(data, &tempMap); err != nil { return err } fc.Permissions = make(map[string]bool) for key := range tempMap { // 拆分"permission.权限名"格式的键 parts := strings.SplitN(key, ".", 2) if len(parts) != 2 || parts[0] != "permission" { continue // 跳过不符合格式的键 } permName := parts[1] // 替换为实际权限判断逻辑 fc.Permissions[permName] = permissions.Role == "admin" } return nil } type Item struct { Name string `json:"name"` Path string `json:"path"` Color string `json:"color"` Icon string `json:"icon"` Filter *FilterCondition `json:"filter"` } func main() { // 读取JSON文件(Go 1.16+推荐用os.ReadFile替代ioutil.ReadFile) data, err := os.ReadFile("file.json") if err != nil { panic(err) } var items []Item err = json.Unmarshal(data, &items) if err != nil { panic(err) } // 打印结果 for _, item := range items { fmt.Printf("Name: %s\nPath: %s\nColor: %s\nIcon: %s\nFilter: %+v\n\n", item.Name, item.Path, item.Color, item.Icon, item.Filter) } }
代码说明
- 自定义反序列化:通过
UnmarshalJSON方法,先将filter的JSON内容转成临时map,再遍历键拆分出权限名称(如从permission.IsAdmin提取IsAdmin)。 - 动态权限判断:将JSON中静态的
true替换为permissions.Role == "admin"的动态判断,可根据实际权限规则修改这部分逻辑(如支持多角色、复杂权限校验)。 - 兼容性:如果JSON中存在多个
permission.Xxx格式的键,该方法会自动全部提取到Permissionsmap中。
测试输出
当permissions.Role为"admin"时,运行结果如下:
Name: Develop Path: /develop Color: #E34D20 Icon: DevelopIcon Filter: &{Permissions:map[IsAdmin:true]}
内容的提问来源于stack exchange,提问作者Vishwa Ratna
相关产品推荐
相关产品推荐

