viper4android io错误,Go viper包处理JSON笔记

第一部分 前景提要

一、背景

用Go搭一个小项目, 按传统的套路把开发环境和生产环境配置信息写在配置文件config.json中, 初始化加载配置,解析出数据。看着是解析一个JSON的小事,过程中却发生了3次演进:

1、定义一个配置文件对应的结构体。

2、递归加载配置的全部节点。

3、使用viper

思路1: 是最初的想法,考虑到动态加配置的话,还需要改结构体,这就有点low了,故而并没有实施,仅停留在思考层面;

思路2: 参考网上的一个实现,拿来简单调整了下,发现挺好用,但是发现不能获取一个子节点下的全部key, 要自己实现的话,看看项目的排期,是肯定来不及的;

思路3: 是用现有的开源包viper, 确实好用。

本文就把没有实现和实现了的方案都在这里模拟实现下,希望顺便解释了为什么读个JOSN文件还要用包viper

config.json内容大致如下

{

"dev": {

"dockerAddr": "xxx",

"appName": "office",

"version": "20210315115158",

"tag": "1",

"etcdEnv": {

"endpoint": "https://xxx,https://xxx",

"namespace": "v10",

"prefix": "v10",

"user": "xxx",

"password": "xxx"

}

},

"online": {

"dockerAddr": "xxx",

"appName": "office",

"version": "20210315115158",

"tag": "1",

"etcdEnv": {

"endpoint": "https://xxx,https://xxx",

"namespace": "v10",

"prefix": "v10",

"user": "xxx",

"password": "xxx"

}

},

}

第二部分 定义结构体

一、Go 处理JSON标准库

Go内置处理JSON标准库是encoding/json

其中,两个常用的方法为Marshal和Unmarshal, 分别实现数据的序列号和反序列化。

1、Marshal

func Marshal(v interface{}) ([]byte, error)

2、Unmarshal

func Unmarshal(data []byte, v interface{}) error

二、具体实现

为什么要定义一个结构体,定义一个map不行咩

1、map可转json

https://www.jianshu.com/p/f7f930152482

2、json转map

https://blog.csdn.net/lanyang123456/article/details/78930071

3、struct转json

https://www.cnblogs.com/liuhe688/p/10971327.html

package main

import (

"encoding/json"

"fmt"

"io/ioutil"

)

type EtcdConfig struct {

Endpoint string

Namespace string

Prefix string

User string

Password string

}

type BaseConfig struct {

DockerAddr string

AppName string

Version int

Tag string

EtcdEnv EtcdConfig

}

// Dev和Online必须和json中同名,不然返回空

type Config struct {

Dev BaseConfig

Online BaseConfig

}

func main() {

var config Config

data, err := ioutil.ReadFile("conf/config.json")

if err != nil {

panic(err)

}

err = json.Unmarshal(data, &config)

if err != nil {

panic(err)

}

fmt.Println(config) /

}

以上输出

{{xxx office-dev 101 20210315115158 {https://xxx,https://xxx v10 v10 xxx xxx}} {xxx office-online 1001 20210315115158 {https://xxx,https://xxx v10 v10 xxx xxx}}}

第三部分 递归加载配置

1、加载配置的config包

package config

import (

"encoding/json"

"os"

)

const (

defaultConfigPath = "conf/config.json"

)

var (

raw map[string]interface{}

config = make(map[string]interface{})

)

func loadConfigs(prefix string, o interface{}) {

if m, ok := o.(map[string]interface{}); ok {

if len(prefix) > 0 {

prefix = prefix + ":"

}

for k, v := range m {

key := prefix + k

loadConfigs(key, v)

}

} else {

config[prefix] = o

}

}

func LoadConfigs() (err error) {

file, err := os.Open(defaultConfigPath)

if err != nil {

panic(err)

return

}

decoder := json.NewDecoder(file)

err = decoder.Decode(&raw)

loadConfigs("", raw)

return

}

func String(key string, defaultValue string) (value string) {

value, _ = getString(key, defaultValue)

return

}

func getString(key string, defaultValue string) (value string, found bool) {

v, found := config[key]

if !found {

return defaultValue, false

}

if value, ok := v.(string); ok {

return value, ok

} else {

return defaultValue, false

}

}

2、用法

用冒号分割key, 直接取值即可

func init() {

config.LoadConfigs()

addr := config.String("dev:dockerAddr", "")

fmt.Println(addr)

}

第四部分 使用包viper

一、关于viper

1、一个优秀的读取配置Go包

2、github地址:https://github.com/spf13/viper

二、用法

viper.AddConfigPath("./conf/")

viper.SetConfigName("server")

err := viper.ReadInConfig() // 读取配置数据

if err != nil {

panic(fmt.Errorf("Fatal error config file: %s \n", err))

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值