当前位置: 首页 > news >正文

golang-gin使用中间件处理文本-时间字符串格式

一、问题

面临的问题:需要对已有业务代码修改时间格式,原本的时间格式里面带了一个T。因为时间分散在各处,又没有统一的管理入口。这面临着大量的代码修改,于是想找一个没有那么大修改量的方式。

二、思路

思考了一下,两个地方是肯定会经过的,一个是JSON转化的地方,一个是中间件。

1. 在JSON序列化处修改。

        如果能添加一个类似Python的encoder之类的东西,那么就可以解决所有的日期的序列化。可惜在一番寻找后,并没有发现这样的东西。其间发现gorm支持在tag上添加序列化,但发现gin是直接使用的原生的json模块,并没有走gorm的逻辑。而原生的json没有统一的修改序列化的地方。

2. 在中间件处修改。

        这个是gin支持的中间件机制。之前有使用过。

3. monkey patch到time模块上,修改其序列化方法。

        直接monkey patch修改原生time类型的序列化方法。这类方法比较脏,不确定是否可能有潜在风险。

三、日志

我上手尝试了一下中间件机制。发现可行就没有再继续验证其它方法。

1. 创建一个简单的REST API


package main
import ("regexp""time""github.com/gin-gonic/gin"
)
type StructA struct {FieldA string    `form:"field_a"  binding:"required"`Ctime  time.Time `form:"ctime" binding:"required"`
}
type StructB struct {// 嵌套结构体StructAFieldB string `form:"field_b"`
}
func GetB(c *gin.Context) {// 绑定表单数据至自定义结构体var b StructBb.Ctime = time.Now()c.JSON(200, b)
}
func main() {r := gin.Default()r.GET("/getb", GetB)r.Run()
}

2. 添加中间件


type copyWriter struct {gin.ResponseWriter
}
func (cw copyWriter) Write(b []byte) (int, error) {// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d+)([+-]\d{2}:\d{2})`)time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d{2})\d*([+-]\d{2}:\d{2})`)// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})`)s := string(b)result := time_re.ReplaceAllString(s, "$1 $2")return cw.ResponseWriter.WriteString(result)
}func main() {r := gin.Default()r.Use(func(ctx *gin.Context) {cw := &copyWriter{ResponseWriter: ctx.Writer}ctx.Writer = cwctx.Next()// read data in buf// do something for data// write to ResponseWriter})r.GET("/getb", GetB)r.Run()
}

 其中提供了几种不同输出时间格式的正则:

// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d+)([+-]\d{2}:\d{2})`)time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d{2})\d*([+-]\d{2}:\d{2})`)// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})`)

3. 输出结果如下: 


{"FieldA": "","Ctime": "2024-08-19 19:33:42.75","FieldB": ""
}

还可以根据需要,在中间件中增加过滤条件。例如,在仅支持json格式的过滤,防止将文件下载等里的日期也替换掉。

4. 完整代码


package main
import ("regexp""time""github.com/gin-gonic/gin"
)
type StructA struct {FieldA string    `form:"field_a"  binding:"required"`Ctime  time.Time `form:"ctime" binding:"required"`
}
type StructB struct {// 嵌套结构体StructAFieldB string `form:"field_b"`
}
func GetB(c *gin.Context) {// 绑定表单数据至自定义结构体var b StructBb.Ctime = time.Now()c.JSON(200, b)
}
type copyWriter struct {gin.ResponseWriter
}
func (cw copyWriter) Write(b []byte) (int, error) {// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d+)([+-]\d{2}:\d{2})`)time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}\.\d{2})\d*([+-]\d{2}:\d{2})`)// time_re := regexp.MustCompile(`(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})`)s := string(b)result := time_re.ReplaceAllString(s, "$1 $2")return cw.ResponseWriter.WriteString(result)
}
func main() {r := gin.Default()// 创建一个middleware函数,替换返回中的字符串r.Use(func(ctx *gin.Context) {cw := &copyWriter{ResponseWriter: ctx.Writer}ctx.Writer = cwctx.Next()// read data in buf// do something for data// write to ResponseWriter})r.GET("/getb", GetB)r.Run()
}

  

四、总结

中间件是典型的面向层的,而不是面向对象的思想的产物。利用gin的中间件,基本上可以完成大部分的统一的文本处理需求。

引用:

How to rewrite response body in middleware? · Issue #3384 · gin-gonic/gin (github.com)


http://www.mrgr.cn/news/10930.html

相关文章:

  • 深入理解Pandas:数据处理的核心技能与应用(四)
  • 【红队技巧】.Net免杀 绕过主流杀软
  • SpringBoot文档之Logging的阅读笔记
  • Swift中的可选类型:揭开Optional的神秘面纱
  • 如何使用ssm实现品牌手机销售信息系统
  • 利用机器学习推动 vSOC 检测
  • 【ShuQiHere】从零开始实现逻辑回归:深入理解反向传播与梯度下降
  • Vue55 动画与过度
  • 【openwrt-21.02】openwrt-21.02 T750 按键GPIO自动进入刷机模式功能实现
  • 热点 | 爆款游戏的诞生与游戏出海的持续增长
  • Redis应用
  • 等保测评与企业风险管理:构建坚实的信息安全防线
  • threejs 创建CSS3DSprite精灵标签, 可以更新位置及内容(封装)
  • 编程之路:在Bug的迷宫中寻找出口
  • 【限时秒杀】基于SpringBoot+Vue的智慧旅游攻略系统+LW示例参考
  • 二分查找算法:朴素二分+左右边界二分力扣实战应用
  • 邻接表的具体实例
  • bat 文件, 简化git 操作
  • QT通过信号传递参数至槽函数(不通层级通信)
  • 如何使用ssm实现基于ssm的“游侠”旅游信息管理系统