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

网站建设成本计划深度优化

网站建设成本计划,深度优化,有关建筑网站建设方案案例,购物网站怎么做文章目录1.Gin 的 Middleware2.使用 Middleware 打印请求与回包内容3.多次读取请求 Body 的问题4.多次读取响应 Body 的问题5.小结参考文献在开发 Web 应用程序时,难免不会遇到功能或性能等问题。为了快速定位问题,需要打印请求和响应的内容。本文将介绍…

文章目录

  • 1.Gin 的 Middleware
  • 2.使用 Middleware 打印请求与回包内容
  • 3.多次读取请求 Body 的问题
  • 4.多次读取响应 Body 的问题
  • 5.小结
  • 参考文献

在开发 Web 应用程序时,难免不会遇到功能或性能等问题。为了快速定位问题,需要打印请求和响应的内容。

本文将介绍如何使用 Gin 框架来优雅地打印请求和响应的内容。

1.Gin 的 Middleware

在 Gin 框架中,中间件是一种用于拦截 HTTP 请求和响应的机制。中间件函数可以在请求到达处理程序之前或之后执行某些操作,例如打印请求和响应的内容、验证请求数据等。

Gin 框架提供了一种简单的方法来定义和使用中间件。中间件函数需要满足以下条件:

  • 函数的签名必须是 func(c *gin.Context),其中 c 是 Gin 框架中的上下文对象。
  • 函数可以执行任何操作,但是必须调用 c.Next() 方法来继续执行请求处理程序和其他中间件函数。
  • 如果需要在请求处理程序之后执行某些操作,可以在调用 c.Next() 之后执行。

2.使用 Middleware 打印请求与回包内容

下面是一个使用 Gin 中间件来打印请求和响应内容的示例代码:

func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 记录请求时间start := time.Now()// 打印请求信息reqBody, _ := c.GetRawData()fmt.Printf("[INFO] Request: %s %s %s\n", c.Request.Method, c.Request.RequestURI, reqBody)// 执行请求处理程序和其他中间件函数c.Next()// 记录回包内容和处理时间end := time.Now()latency := end.Sub(start)respBody := string(c.Writer.Body.Bytes())fmt.Printf("[INFO] Response: %s %s %s (%v)\n", c.Request.Method, c.Request.RequestURI, respBody, latency)}
}func main() {r := gin.Default()// 注册中间件r.Use(Logger())r.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "Hello, World!")})r.Run(":8080")
}

上面的代码定义了一个中间件,用来记录请求和回包内容。在中间件中,我们首先记录请求的时间和请求内容,然后调用 c.Next() 继续处理请求。在请求处理完成后,我们记录回包内容和处理时间。最后,我们使用 gin.Default() 函数来创建一个 Gin 引擎实例,并注册路由和中间件。启动服务后,我们可以访问http://localhost:8080/hello查看请求和回包的内容。

3.多次读取请求 Body 的问题

实际上,上面的做法会有问题。

在中间件中读取了请求的 Body,如果在接口处理函数中再次读取 Body,会导致 Body 被读取两次,从而出现问题。 因为在读取 Body 后,Body 的指针会被移到末尾,第二次读取时就无法再次读取到内容。

那么 Gin 如何正确多次读取 http request body 的内容呢?

解决思路: 由于 Request.Body 为公共变量,我们在对原有的 buffer 读取完成后,只要手动创建一个新的 buffer 然后以同样接口形式替换掉原有的 Request.Body 即可。

reqBytes, _ := c.GetRawData()// 请求包体写回。
if len(reqBytes) > 0 {c.Request.Body = io.NopCloser(bytes.NewBuffer(reqBytes))
}

在 Go 语言中,io.NopCloser 函数返回一个实现 io.ReadCloser 接口的对象,这个对象可以包装任何实现 io.Reader 接口的对象,并提供了一个空的 Close 方法。这个方法的作用就是什么也不做,仅仅是返回一个 nil 的 error。

通常情况下,我们会使用 io.ReadCloser 接口读取数据,并在读取完成后关闭相关资源,例如打开的文件句柄或者网络连接等。但是在某些场景下,我们希望读取数据,但是并不想关闭相关资源,比如在数据读取完成后还需要进行一些其他操作,或者需要多次读取同一个资源等。

这时候,就可以使用 io.NopCloser 函数将一个实现了 io.Reader 接口的对象包装成一个实现了 io.ReadCloser 接口的对象,并在 Close 方法中什么也不做。这样就可以在读取数据后不关闭相关资源,从而方便进行其他操作或者多次读取同一个资源。

4.多次读取响应 Body 的问题

同样地,在中间件中读取响应 Body 的问题是,它会使得缓冲区被读取完毕,指针指向了缓冲区的末尾,而后续的代码再次读取 Body 时,指针已经到了缓冲区的末尾,无法再次读取。

为了避免这个问题,我们可以使用一个自定义的 ResponseWriter 来替换 Gin 默认的 ResponseWriter。自定义的 ResponseWriter 可以将响应 Body 写入到一个内存缓冲区中,并在中间件中获取响应 Body 并记录日志。

下面是一个完整的可以在日志中间件中读取请求与响应 Body 的示例。

// CustomResponseWriter 封装 gin ResponseWriter 用于获取回包内容。
type CustomResponseWriter struct {gin.ResponseWriterbody *bytes.Buffer
}func (w CustomResponseWriter) Write(b []byte) (int, error) {w.body.Write(b)return w.ResponseWriter.Write(b)
}// 日志中间件。
func Logger() gin.HandlerFunc {return func(c *gin.Context) {// 记录请求时间start := time.Now()// 使用自定义 ResponseWritercrw := &CustomResponseWriter{body:           bytes.NewBufferString(""),ResponseWriter: c.Writer,}c.Writer = crw// 打印请求信息reqBody, _ := c.GetRawData()fmt.Printf("[INFO] Request: %s %s %s\n", c.Request.Method, c.Request.RequestURI, reqBody)// 执行请求处理程序和其他中间件函数c.Next()// 记录回包内容和处理时间end := time.Now()latency := end.Sub(start)respBody := string(crw.body.Bytes())fmt.Printf("[INFO] Response: %s %s %s (%v)\n", c.Request.Method, c.Request.RequestURI, respBody, latency)}
}

5.小结

在本文中,我们介绍了为什么要打印请求与回包内容,以及如何使用 Gin 的 Middleware 功能来打印请求和回包内容。通过打印请求和回包内容,我们可以更好地了解 API 的执行过程,并且可以快速定位问题。


参考文献

OpenAI ChatGPT
Using middleware | Gin Web Framework
如何让gin正确多次读取http request body内容- 掘金
如何让gin 正确读取http response body 内容,并多次使用- 掘金

http://www.tj-hxxt.cn/news/38334.html

相关文章:

  • 做网站开发需要学什么软件自己建网页
  • 网站建设开发的目的做推广网络
  • 三亚房产做公示是什么网站友情链接交换统计表
  • 深圳外包网站制作公司滨州网站建设
  • 建设网站是哪个部门负责营销手机系统安装
  • 如何做网站广告图片青岛网站制作公司
  • ysl免费网站建设网络运营培训班多少钱
  • 织梦后台做的网站怎么绑定域名成免费crm特色
  • 文章修改网站网络开发
  • 网站服务器租用开票应该口碑营销的成功案例
  • 同城分类信息网站seo点击排名软件营销工具
  • 网站开发用什么好河南整站关键词排名优化软件
  • 百度免费seo湖南网站建设seo
  • 想把一个网站屏蔽了怎么做系统优化大师
  • 湖南在线淘宝怎样优化关键词
  • 遵义做网站多少钱网址提交入口
  • 网站建设 用什么语言营销网站系统
  • 网站设计公司需要什么资质一键搭建网站工具
  • 阿里巴巴网站的功能seo托管服务
  • 龙岗南联网站建设博客seo怎么做
  • 拿word如何做网站网络营销的特点举例说明
  • 国展做网站的公司互动营销案例
  • 从域名到网站网络舆情分析师
  • 醴陵网站建设厦门网络推广
  • idc主机托管seo排名点击器曝光行者seo
  • 上海网站建设制作微信百度开户返点
  • 手机网站搭建seo网站推广费用
  • 有哪些做网站公司市场营销主要学什么
  • 上海做网站seosem工资
  • 青岛网站建设服务百度搜索引擎工作原理