Viper反序列化解析字段不成功问题

Viper反序列化解析字段不成功问题

问题背景

通过viper解析文件内容映射config一直失败,相关代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
type Config struct {
DBConf *DBConf `toml:"db"`
RedisConf *RedisConf `toml:"redis"`
WebConfig *WebConfig `toml:"app"`
}

type DBConf struct {
Read struct {
Dsn string `toml:"dsn"` // 最高优先级
} `toml:"read"`
Write struct {
Dsn string `toml:"dsn"` // 最高优先级
} `toml:"write"`
Base struct {
Type string `toml:"type"`
MaxOpenConn int `toml:"maxOpenConn"`
MaxIdleConn int `toml:"maxIdleConn"`
ConnMaxLifeTime time.Duration `toml:"connMaxLifeTime"`
} `toml:"base"`
}

type CacheType string

type RedisConf struct {
Address string `toml:"addr"`
DB string `toml:"db"`
Password string `toml:"password"`
}

type WebConfig struct {
Port string `toml:"port"`
IsDebug bool `toml:"debug"`
LogFilePath string `toml:"path"`
}
appFullPath := "./conf/" + filePath
// 解析 config
viper.SetConfigName("web")
viper.AddConfigPath(appFullPath)
viper.SetConfigType("yaml")
err := viper.ReadInConfig()
if err != nil {
log.Fatal("解析文件失败: ", err)
}
if err := viper.Unmarshal(&conf); err != nil {
log.Fatal("解析文件失败: ", err)
}
// 监听配置更新
viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
if err := viper.Unmarshal(&conf); err != nil {
log.Fatal("解析文件失败: ", err)
}
})

问题原因

image.png

Viper使用的是 github.com/mitchellh/mapstructure来解析值
mapstructure 用于将通用的map[string]interface{}解码到对应的 Go 结构体中
默认情况下,mapstructure 使用结构体中字段的名称做这个映射,不区分大小写,比如 Name 字段可以映射到
name、NAME、NaMe 等等,如果名称不一致没有指定 tagName ,则默认为 mapstructure,这也是为什么带下划线或者名称不一致的字段不加 mapstructure标签无法解析的原因

解决方案

mapstructure方法

通过mapstructure映射名称

image.png


Viper反序列化解析字段不成功问题
https://blog.longpi1.com/2024/03/08/Viper反序列化解析字段不成功问题/