首页
📷在线壁纸
🎬娱乐天地
🔖友情链接
更多
📝留言板
Search
1
【javascript】JS-向当前url追加参数
2,345 阅读
2
【PHP】生成随机昵称
2,219 阅读
3
【PHP】判断一个字符串是否属于序列化后的数据
2,024 阅读
4
【css】html+css给文章页,做阅读全文
1,975 阅读
5
【PHP】 设计模式(23种)
1,910 阅读
📂默认分类
💓typecho
🏳️🌈代码改变世界
🍇 mysql
🍈 Winform
🍓 golang
🍉 设计模式
🥝 PHP
🍎 python
🍊 nginx
🍋 网络安全
🍍 javascript
🫑 database
🍭文艺范
🍏mac
AI
LLM
image
audio
yolo
3D
code
登录
Search
标签搜索
php
typecho
代码注释
redis
mysql
go
golang
nginx
thinkphp
docker
gin
linux
curl
html
mamp
算法
短网址
构造函数
webhook
代码片段
依然范儿特西
累计撰写
145
篇文章
累计收到
1
条评论
首页
栏目
📂默认分类
💓typecho
🏳️🌈代码改变世界
🍇 mysql
🍈 Winform
🍓 golang
🍉 设计模式
🥝 PHP
🍎 python
🍊 nginx
🍋 网络安全
🍍 javascript
🫑 database
🍭文艺范
🍏mac
AI
LLM
image
audio
yolo
3D
code
页面
📷在线壁纸
🎬娱乐天地
🔖友情链接
📝留言板
搜索到
3
篇与
的结果
2024-02-28
golang 编程规范 - 项目目录结构
参考链接 https://makeoptim.com/golang/standards/project-layout#google_vignette针对API使用的目录结构, 如果有用作其他服务,可以灵活调整 ├── api (项目对外提供和依赖的 API 文件) │ └── dao │ └── http │ └── v1 │ └── v2 │ └── middleware │ └── model │ └── router │ └── service │ └── validator │ ├── cmd (当前项目的可执行文件) │ └── ├── internal (私有的应用程序代码库) │ └── ├── configs (配置文件和初始化文件) │ └── ├── global (全局变量) │ └── ├── deploy (IaaS,PaaS,系统和容器编排部署配置和模板) │ └── ├── pkg (外部应用程序可以使用的库代码) │ └── ├── scripts (用于执行各种构建,安装,分析等操作的脚本) │ └── ├── third_parth (外部辅助工具) │ └── ├── test (单元测试) │ └── ├── vendor (应用程序的依赖关系) │ └──
2024年02月28日
21 阅读
0 评论
1 点赞
2024-02-28
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
在学习Golang中的gin框架的时候,遇到了下面的warning :[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.对于上面的WARNING翻译出来之后也就是 : 您信任所有代理,这是不安全的。我们建议您设置一个值。对于Goland编译器给出的建议 :Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all- proxies for details.也就是去看文档去了解细节,额,好像又啥也没说!那么怎么解决呢?根据warning也就是给gin设置一个信任ip : 127.0.0.1代码 :router := gin.Default() router.SetTrustedProxies([]string{"127.0.0.1"})
2024年02月28日
1 阅读
0 评论
1 点赞
2023-10-10
Gin 框架在中间件中获取 response body 的方法
在写一个Gin框架日志中间件的时候,需要记录请求和响应相关的一些数据,例如请求参数、请求方法、请求时间、请求头、耗时、响应状态码、响应数据等,gin为获取这些数据基本都提供了现成的方法,但是获取响应数据还是有一定难度和复杂度的。那么,该如何获取响应数据也就是 response body 呢?先上代码。代码示例1、先写一个 middleware ,简单打印一下 response bodypackage middleware import ( "bytes" "fmt" "github.com/gin-gonic/gin" ) //自定义一个结构体,实现 gin.ResponseWriter interface type responseWriter struct { gin.ResponseWriter b *bytes.Buffer } //重写 Write([]byte) (int, error) 方法 func (w responseWriter) Write(b []byte) (int, error) { //向一个bytes.buffer中写一份数据来为获取body使用 w.b.Write(b) //完成gin.Context.Writer.Write()原有功能 return w.ResponseWriter.Write(b) } func PrintResponse(c *gin.Context) { writer := responseWriter{ c.Writer, bytes.NewBuffer([]byte{}), } c.Writer = writer c.Next() fmt.Println("response body:" + writer.b.String()) } 2、引用 middleware ,看看效果package main import ( "github.com/gin-gonic/gin" "hello/middleware" "net/http" ) func main() { r := gin.New() //添加获取响应内容 middleware r.Use(middleware.PrintResponse) r.GET("/test", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"name": "laofan"}) }) // Listen and Server in 0.0.0.0:8080 r.Run(":8080") } 打开浏览器访问http://127.0.0.1:8080/test ,即可在控制台中看到 response body 的输出内容response body:{"name":"laofan"}原理通过上面的代码可以看出,gin 通过调用如下方法写入了 response bodyc.JSON(http.StatusOK, gin.H{"name": "laofan"})追进 JSON 方法,源码如下,调用了 Render 方法package gin func (c *Context) JSON(code int, obj interface{}) { c.Render(code, render.JSON{Data: obj}) }追进 Render 方法, 可以看出 gin.Context.Writer 作为参数传给了 r.Render() 方法,这里形参 r 的实参为 render.JSON{Data: obj} ,所以实际调用的是 func (r JSON) Render(w http.ResponseWriter) 方法。package gin // Render writes the response headers and calls render.Render to render data. func (c *Context) Render(code int, r render.Render) { c.Status(code) if !bodyAllowedForStatus(code) { r.WriteContentType(c.Writer) c.Writer.WriteHeaderNow() return } if err := r.Render(c.Writer); err != nil { panic(err) } } func (r JSON) Render(w http.ResponseWriter) 源码如下package render // Render (JSON) writes data with custom ContentType. func (r JSON) Render(w http.ResponseWriter) (err error) { if err = WriteJSON(w, r.Data); err != nil { panic(err) } return } // WriteJSON marshals the given interface object and writes it with custom ContentType. func WriteJSON(w http.ResponseWriter, obj interface{}) error { writeContentType(w, jsonContentType) jsonBytes, err := json.Marshal(obj) if err != nil { return err } _, err = w.Write(jsonBytes) return err } 在 func (r JSON) Render() 方法中,gin.Context.Writer 被传到了 WriteJSON() 方法中,最终写入数据调用的是 gin.Context.Writer.Write() 方法。gin.ResponseWriter 源码如下package gin type Context struct { //... writermem responseWriter Writer ResponseWriter //... } // ResponseWriter ... type ResponseWriter interface { //... http.ResponseWriter //... } 可以看出 gin.Context.Writer 类型为 interface gin.ResponseWriter。package http type ResponseWriter interface { //... Write([]byte) (int, error) //... } 要实现 gin.ResponseWriter 接口,必须实现Write([]byte) (int, error) 方法。所以写入 response body 调用的是 gin.Context.Writer.Write() 方法,gin.Context.Writer 需要是type gin.ResponseWriter interface 的一个具体实现。到此,可以看出上面代码示例的思路:实现 type gin.ResponseWriter interface 并重写 Write([]byte) (int, error) 方法,该方法在实现 gin.Context.Writer.Write() 原有功能的同时,再向一个 bytes.buffer 中写一份数据来用于获取 response body 使用。
2023年10月10日
5 阅读
0 评论
0 点赞