【Go】十一、标准化请求返回与viper管理配置文件的简单使用

请求返回的返回方法

这里指的是:传参的方式,类似与Java的r.setData()

创建目录:

user-web

global

response

user.go

定义一个结构体用于接收返回值,这里的 json 属于将对象转换为 json 时的规则定义。

时间处理

方法一:在方法返回处处理(不完全)

这种处理方式还不完全,其只能将时间转换为 标准时间格式

user.go:

package responseimport "time"type UserResponse struct {Id       int32     `json:"id"`NickName string    `json:"name"`Birthday time.Time `json:"birthday"`Gender   string    `json:"gender"`Mobile   string    `json:"mobile"`
}

在使用这个结构体时,应该对 rsp.Data 进行处理:

但此时,返回的数据是 :“0001-01-01T00:00:00Z” 类似于这样的标准时间格式

api:

	// 构建请求结果result := make([]interface{}, 0)for _, value := range rsp.Data {user := response.UserResponse{Id:       value.Id,NickName: value.NickName,Birthday: time.Time(time.Unix(Int64(value.BirthDay), 0)),Gender: value.Gender,Mobile: value.Mobile,}result = append(result, user)}// 利用上下文的 JSON 转换返回结果,在这里将结果返回给请求ctx.JSON(http.StatusOK, result)

方法二:传入string 在方法返回处处理时间字符串

所以这里我们采用 string 的传递处理时间的格式问题,将 Birthday 作为 string 类型进行传递,在输出返回的时候进行 Format

user.go

package responsetype UserResponse struct {Id       int32  `json:"id"`NickName string `json:"name"`//Birthday time.Time `json:"birthday"`Birthday stringGender   string `json:"gender"`Mobile   string `json:"mobile"`
}

api:

	// 构建请求结果result := make([]interface{}, 0)for _, value := range rsp.Data {//data := make(map[string]interface{}) // 创建一个 map//data["id"] = value.Id//data["name"] = value.NickName//data["birth"] = value.BirthDay//data["gender"] = value.Gender//data["mobile"] = value.Mobilevar user = response.UserResponse{Id:       value.Id,NickName: value.NickName,Birthday: time.Time(time.Unix(int64(value.BirthDay), 0)).Format("2006-01-02"),Gender: value.Gender,Mobile: value.Mobile,}result = append(result, user)}

方法三:利用别名重写 MarshalJSON 的方式直接在返回结构体中处理

另外,如果希望 response 的类型直接是 time.Time 的话,就实现 jsonTime 方法来对json格式的时间进行转换

user.go

package responseimport ("fmt""time"
)type JsonTime time.Time // 给 time.Time 类型定义一个别名:JsonTimefunc (j JsonTime) Marsha1JSON() ([]byte, error) {var stmp = fmt.Sprintf("\"%s\"", time.Time(j).Format("2006-01-02"))return []byte(stmp), nil
}type UserResponse struct {Id       int32     `json:"id"`NickName string    `json:"name"`Birthday time.Time `json:"birthday"`//Birthday stringGender string `json:"gender"`Mobile string `json:"mobile"`
}

api:

	// 构建请求结果result := make([]interface{}, 0)for _, value := range rsp.Data {//data := make(map[string]interface{}) // 创建一个 map//data["id"] = value.Id//data["name"] = value.NickName//data["birth"] = value.BirthDay//data["gender"] = value.Gender//data["mobile"] = value.Mobilevar user = response.UserResponse{Id:       value.Id,NickName: value.NickName,Birthday: response.JsonTime(time.Unix(int64(value.BirthDay), 0)),	Gender: value.Gender,Mobile: value.Mobile,}result = append(result, user)}

传入的 time.Time (JsonTime)类型输出为

{0 63852321095 0x132ba20}

time.Time(j) 进行标准化之后输出为:

2024-05-26 19:51:35 +0800 CST

这主要是由于 time.Time 定义了 String 方法,可以被 fmt.Print 友好的打印,而 JsonTime 是一个别名,其没有继承其方法,所以其展现仅仅是内存中的表现形式,内容其实是一样的。

这里要注意的是,我们定义 JsonTime的原因是:我们无法重写修改源代码中的 time.Time,需要通过别名作为跳板

而 []byte(str) 的一种原因是,JSON 格式的转换需要使用 二进制作为跳板(可以先这样理解,具体原因有待考究)

配置文件管理

简单条件下的配置文件管理

这里选用,生态最好,使用最广泛的 yaml 作为配置文件来管理配置信息

同时 使用 viper 库对yaml 进行管理,这里的 viper 库是一个强大的配置文件管理库,其不仅仅可以管理 ymal,也支持 java properties、JSON、TOML、HCL、envfile 的管理

文件目录:

viper_test

test

main.go

config.yaml

简单获取配置文件信息

config.yaml:

name: "user-webbbb"

main.go:

package mainimport ("fmt""github.com/spf13/viper"
)/*1. 创建 viper 对象2. 设置配置文件路径3. 读取配置文件4. 使用配置
*/func main() {v := viper.New()// 注意这里的文件配置路径要根据 go build 中的 Edit Config 来考量,不可以根据当前文件来考量v.SetConfigFile("other_test/viper_test/ch01/config.yaml")if err := v.ReadInConfig(); err != nil {panic(err)}fmt.Println(v.Get("name"))
}

使用结构体直接映射配置信息

config.yml

name: "user-webbbb"
port: 8021

main.go

package mainimport ("fmt""github.com/spf13/viper"
)/*简单读取配置文件1. 创建 viper 对象2. 设置配置文件路径3. 读取配置文件4. 使用配置
*//*配置文件映射为 struct1. 创建对象2. 设置路径3. 读取配置文件4. 创建对应的结构体对象5. 使用 v.unmarsshal 进行反解,传入地址
*/type ServerConfig struct {ServiceName string `mapstructure:"name"` // 使用 mapstructure 来反解配置文件Port        int64  `mapstructure:"port"`
}func main() {v := viper.New()// 注意这里的文件配置路径要根据 go build 中的 Edit Config 来考量,不可以根据当前文件来考量v.SetConfigFile("other_test/viper_test/ch01/config.yaml")if err := v.ReadInConfig(); err != nil {panic(err)}serverConfig := ServerConfig{}if err := v.Unmarshal(&serverConfig); err != nil {panic(err)}fmt.Println(serverConfig)//fmt.Println(v.Get("name"))
}

复杂条件下的配置管理

若遇到多层 yml 的情况,只需要嵌套 yml 即可

config.yaml:

name: 'user-web'
mysql:host: '127.0.0.1'port: 3306

main.go:

package mainimport ("fmt""github.com/spf13/viper"
)type MysqlConfig struct {Host string `mapstructure:"host"`Port int64  `mapstructure:"port"`
}type ServerConfig struct {ServerName  string      `mapstructure:"name"`ServerMysql MysqlConfig `mapstructure:"mysql"`
}func main() {v := viper.New()v.SetConfigFile("other_test/viper_test/ch02/config.yaml")if err := v.ReadInConfig(); err != nil {panic(err)}serverConfig := ServerConfig{}if err := v.Unmarshal(&serverConfig); err != nil {panic(err)}fmt.Print(serverConfig)
}

配置文件的隔离性管理

实现配置文件在不同情况下的不同选择,其原理是识别系统的环境变量,若系统的xxx环境变量为true 则为xxx环境,使用对应的配置文件

// 获取环境变量
func GetEnvInfo(env string) bool {viper.AutomaticEnv()return viper.GetBool(env)
}func main() {configFileName := "other_test/viper_test/ch02/config-prod.yaml"debug := GetEnvInfo("MXSHOP-DEBUG")if debug {configFileName = "other_test/viper_test/ch02/config-dev.yaml"}v := viper.New()v.SetConfigFile(configFileName)if err := v.ReadInConfig(); err != nil {panic(err)}serverConfig := ServerConfig{}if err := v.Unmarshal(&serverConfig); err != nil {panic(err)}fmt.Print(serverConfig)}

此时,我们本地是有这个环境变量的,系统会自动帮我们用我们自己的配置文件,但服务器上是没有这个环境变量的,所以我们的配置文件就会自动被识别为生产环境的配置文件

配置文件的实时识别

	v.WatchConfig()// 此处是固定写法,当监听到文件信息改变时,会触发下面的匿名函数v.OnConfigChange(func(e fsnotify.Event) {fmt.Println("config file channed: ", e.Name) // e.Name 是文件名_ = v.ReadInConfig()_ = v.Unmarshal(&serverConfig)fmt.Println(serverConfig)})// 此处阻塞了主线程,上面的监听还可以继续的根本原因是 viper 中的监听是启用了一个 goroutine进行的,所以主线程的阻塞不妨碍监听进程的持续运行time.Sleep(time.Second * 300)

配置文件集成到项目中

目录结构:

mxshop-api

user-web

api

router

config

config.go (记录匹配过来的配置文件信息)

initialize

config.go

global

global.go

config-debug.yaml

config-pro.yaml

config-debug.yaml

name: "user-webb"
user_srv:host: '127.0.0.1'port: 50051

global.go

package globalimport "mxshop-api/user-web/config"// 全局变量
var (ServerConfig *config.ServerConfig = &config.ServerConfig{}
)

添加初始化信息:

config.go

package initializeimport ("fmt""github.com/fsnotify/fsnotify""github.com/spf13/viper""go.uber.org/zap""mxshop-api/user-web/global"
)// 获取bool型环境变量的方法
func GetenvInfo(env string) bool {viper.AutomaticEnv()var rs boolrs = viper.GetBool(env)return rs
}func InitConfig() {configFileName := "user-web/config-pro.yaml"debug := GetenvInfo("MXSHOP-DEBUG")if debug {configFileName = "user-web/config-debug.yaml"}v := viper.New()v.SetConfigFile(configFileName)if err := v.ReadInConfig(); err != nil {panic(err)}// 注意这里应该是全局变量,全局变量的部署应该是在 global 目录中//serverConfig := config.ServerConfig{}if err := v.Unmarshal(global.ServerConfig); err != nil {panic(err)}zap.L().Info(fmt.Sprintf("配置信读取:%v", global.ServerConfig))v.WatchConfig()v.OnConfigChange(func(e fsnotify.Event) {zap.S().Infof("配置文件产生变化:%s", e.Name)v.ReadInConfig()v.Unmarshal(global.ServerConfig)zap.L().Info(fmt.Sprintf("修改了配置信息:%v\n", global.ServerConfig))})}

在主程序中将初始化信息添加输出文件内容

main.go:

func main() {...// 调用配置文件伛initialize.InitConfig()...}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18851.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器分配问题】

问题: 现有设备n台,可投放到m个项目中,每个项目的产量与投入该项目的设备数量有关。如表2所示为三个项目的产量(吨)和投入设备(台)的关系。求对m个项目的最优设备分配,使总产量效益…

2024年QMT智能量化交易全解读:一文带你深入了解什么是QMT

随着科技的飞速发展和金融市场的日益成熟,量化交易逐渐成为投资者关注的焦点。QMT(Quantitative Market Trading)智能量化交易系统,作为量化交易领域的重要工具,以其高效、精准、自动化的特点,受到越来越多…

【TensorFlow深度学习】Dropout层工作原理与实际运用

Dropout层工作原理与实际运用 Dropout层工作原理与实际运用Dropout:随机失活的艺术工作机制实现代码示例实际运用成效结语 Dropout层工作原理与实际运用 在深度学习的征途中,模型的过拟合问题一直是研究者们面临的一大挑战。过拟合意味着模型在训练数据…

Ableton Live 11 Suite for Mac:音乐创作的全能伙伴

在数字音乐创作的广阔天地中,Ableton Live 11 Suite for Mac无疑是一颗璀璨的明星。作为一款专业的音乐制作软件,它集合了音频录制、编辑、混音、母带制作等全方位功能,为Mac用户提供了无与伦比的音乐创作体验。 Ableton Live 11 Suite拥有直…

Ubuntu/Linux 安装Paraview

文章目录 0. 卸载已有ParaView1. 安装ParaView1.1 下载后安装 2.进入opt文件夹改名3. 更改启动项4. 创建硬链接5. 添加桌面启动方式6. 即可使用 0. 卸载已有ParaView YUT 1. 安装ParaView https://www.paraview.org/ 1.1 下载后安装 找到下载的文件夹,文件夹内…

NTLM Relay Gat:自动化NTLM中继安全检测工具

关于NTLM Relay Gat NTLM Relay Gat是一款功能强大的NTLM中继威胁检测工具,该工具旨在利用Impacket工具套件中的ntlmrelayx.py脚本在目标环境中实现NTLM中继攻击风险检测,以帮助研究人员确定目标环境是否能够抵御NTLM中继攻击。 功能介绍 1、多线程支持…

日用百货元宇宙 伊利牛奶亮相博鳌论坛

近日,博鳌亚洲论坛2024年会在海南博鳌举行,本次年会以“亚洲与世界:共同的挑战,共同的责任”为主题,受到了亚洲各国的高度重视。在本次论坛上,伊利牛奶旗下的金典鲜牛奶作为博鳌亚洲论坛2024年年会官方唯一指定鲜奶亮相,以顶配鲜活营养,向世界贡献中国的健康方案。据悉,这是伊利…

AdaBoost 乳腺癌数据挖掘

目录 1.数据集背景 2 集成学习方法 AdaBoost集成过程 3 个体学习器 结果评价 准确率以及混淆矩阵 评估集成学习模型的泛化学习能力 评估集成学习模型的多样性 结论 源码 1.数据集背景 乳腺癌数据集是一个非常经典的二元分类数据集,被广泛应用…

LSTM长短时记忆网络:推导与实现(pytorch)

LSTM长短时记忆网络:推导与实现(pytorch) 背景推导遗忘门输入门输出门 LSTM的改进:GRU实现 背景 人类不会每秒钟都从头开始思考。当你阅读这篇文章时,你会根据你对以前单词的理解来理解每个单词。你不会把所有东西都扔…

Camunda 7.x 系列【64】实战篇之挂起、删除流程模型

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 前后端基于若依:https://gitee.com/y_project/RuoYi-Vue 流程设计器基于RuoYi-flowable:https://gi…

2024年6月1日(星期六)骑行禹都甸

2024年6月1日 (星期六)骑行禹都甸(韭葱花),早8:30到9:00,昆明氧气厂门口集合,9:30准时出发【因迟到者,骑行速度快者,可自行追赶偶遇。】 偶遇地点:昆明氧气厂门口集合 ,…

Linux系统维护

1. 批量安装部署 2. 初始化配置 3. 禁用Selinux 永久更改 SELinux 配置: 编辑 SELinux 配置文件:使用文本编辑器打开 /etc/selinux/config 文件: 在配置文件中,找到 SELINUX… 的行。将其值更改为以下选项之一: e…

TypeScript 学习笔记(七):TypeScript 与后端框架的结合应用

1. 引言 在前几篇学习笔记中,我们已经探讨了 TypeScript 的基础知识和在前端框架(如 Angular 和 React)中的应用。本篇将重点介绍 TypeScript 在后端开发中的应用,特别是如何与 Node.js 和 Express 结合使用,以构建强类型、可维护的后端应用。 2. TypeScript 与 Node.js…

YoloV8改进策略:BackBone|融合改进的HCANet网络中的多尺度前馈网络(MSFN)|二次创新|即插即用

本文使用HCANet网络中的多尺度前馈网络来提高Backbone的表征能力和检测精度。即插即用,方便大家移植自己的模型中。 论文指导 原论文中的表述 B. 多尺度前馈网络 在 V i T \mathrm{ViT} ViT 中的原始 FFN 是由两个线性层所构成,这样的设计仅用于单尺度特征聚合。但是,F…

2024 GIAC 全球互联网架构大会:拓数派向量数据库 PieCloudVector 架构设计与案例实践

5月24-25日,msup 和高可用架构联合举办了第11届 GIAC 全球互联网架构大会。会议聚焦“共话AI技术的最新进展、架构实践和未来趋势”主题,邀请了 100 余位行业内的领军人物和革新者,分享”Agent/RAG 技术、云原生、基座大模型“等多个热门技术…

浏览器修改后端返回值

模拟接口响应和网页内容 通过本地覆盖可以模拟接口返回值和响应头,无需 mock 数据工具,比如(Requestly),无需等待后端支持,快速复现在一些数据下的 BUG 等。在 DevTools 可以直接修改你想要的 Fetch/XHR 接…

event.preventDefault()使用指南

event.preventDefault(); 是 JavaScript 中用于阻止默认事件行为的方法。具体而言,它在处理 HTML 元素(如链接和表单)的事件时非常有用。下面是详细的解释和示例,说明它的作用和使用场景。 解释 在 HTML 中,许多元素…

将四种算法的预测结果绘制在一张图中

​ 声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 之前的一期推文中,我们推出了…

RPA在抖音等短视频创作开发的应用

相较于一般人对Ai的漠视或仅仅停留在逗比对话而言,在凭此谋生的专业的行当,或AI应用相对宽泛的领域。融合Ai的自动化辅助办公(创作、演示等)的进步日新月异,这方面的知识还是应尽快了解。 RPA是Robotic process autom…

【ROS2问题记录】ros2 bag play xx.db3失败

报错内容: nvidiaoceanstar:~/yolov8_ros2-Tensorrt$ ros2 bag play rosbag2_2024_04_24-13_55_03_0.db3 /opt/ros/foxy/bin/ros2:6: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html fr…