gin框架使用注意事项

本文就说下这段时间我在使用gin框架过程中遇到的问题和要注意的事情。

错误处理请求返回要使用c.Abort,不要只是return

当在controller中进行错误处理的时候,发现一个错误,往往要立即返回,这个时候要记得使用gin.Context.Abort 或者其相关的函数。

类似于:

if err != nil {
c.AbortWithStatus(500)
return
}

这个Abort函数本质是提前结束后续的handler链条,(通过将handler的下标索引直接变化为 math.MaxInt8 / 2 )但是前面已经执行过的handler链条(包括middleware等)还会继续返回。

gin的Abort系列的几个函数为:

func (c *Context) Abort()
func (c *Context) AbortWithStatus(code int)
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{})
func (c *Context) AbortWithError(code int, err error)

gin的错误处理

gin本身默认加载了Recovery()的中间件,所以在不知道如何处理error的时候,可以直接panic出去

如何获取response的body

需求来源于我要做个gin的中间件,请求进来的时候记录一下请求参数,请求出去的时候记录一下请求返回值。在记录请求返回值的时候,我就需要得到请求的返回内容。但是context里面只有一个结构:

Writer    gin.ResponseWriter

所以这里基本思路就是创建一个Writer,它继承gin.ResponseWriter。同时,它又有一个byte.buffer来copy一份数据。

// bodyLogWriter是为了记录返回数据到log中进行了双写
type bodyLogWriter struct {
gin.ResponseWriter
body *bytes.Buffer
} func (w bodyLogWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}

所以,在middleware中就应该这么写

sTime := time.Now()

blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = blw c.Next() // 请求结束的时候记录
duration := fmt.Sprintf("%fms", float64(time.Now().Sub(sTime).Nanoseconds()) / 1000000.0)
handler.Tracef(c.Request.Context(), logger.DLTagRequestOut,
"proc_time=%s||response=%s",
duration,
blw.body.String())

主要就是在Next之前吧context.Writer用我们定义的Writer给替换掉,让它输出数据的时候写两份。

如何获取所有的请求参数

这个其实和gin框架没有啥关系,我刚开始使用的时候以为使用request.ParseForm,然后在request.Form中就能得到了。

结果发现当我的Content-type为multipart/form-data的时候,竟然解析不到数据。

追到ParseForm里面发现,http/request.go里面有这么一个部分代码

case ct == "multipart/form-data":
// handled by ParseMultipartForm (which is calling us, or should be)
// TODO(bradfitz): there are too many possible
// orders to call too many functions here.
// Clean this up and write more tests.
// request_test.go contains the start of this,
// in TestParseMultipartFormOrder and others.
}

我的golang版本是1.11.4。当content-type为multipart/form-data的时候是空的调用的。

当然注释也写很清楚了,建议使用ParseMultipartForm

所以获取http参数的函数我就写成这个样子:

// 这个函数只返回json化之后的数据,且不处理错误,错误就返回空字符串
func getArgs(c *gin.Context) []byte {
if c.ContentType() == "multipart/form-data" {
c.Request.ParseMultipartForm(defaultMemory)
} else {
c.Request.ParseForm()
}
args, _ := json.Marshal(c.Request.Form)
return args
}

gin框架使用注意事项的更多相关文章

  1. GoWeb之gin框架

    Gin 是一个 go 写的 web 框架,具有高性能的优点.官方地址:https://github.com/gin-gonic/gin 一.快速上手 安装 go mod init go get -u ...

  2. 基于gin框架和jwt-go中间件实现小程序用户登陆和token验证

    本文核心内容是利用jwt-go中间件来开发golang webapi用户登陆模块的token下发和验证,小程序登陆功能只是一个切入点,这套逻辑同样适用于其他客户端的登陆处理. 小程序登陆逻辑 小程序的 ...

  3. Gin框架源码解析

    Gin框架源码解析 Gin框架是golang的一个常用的web框架,最近一个项目中需要使用到它,所以对这个框架进行了学习.gin包非常短小精悍,不过主要包含的路由,中间件,日志都有了.我们可以追着代码 ...

  4. gin框架学习手册

    前言 gin框架是go语言的一个框架,框架的github地址是:https://github.com/gin-gonic/gin 转载本文,请标注原文地址:https://www.cnblogs.co ...

  5. go的gin框架从请求中获取参数的方法

    前言: go语言的gin框架go里面比较好的一个web框架, github的start数超过了18000.可见此框架的可信度 如何获取请求中的参数 假如有这么一个请求: POST   /post/te ...

  6. MUI框架-02-注意事项-适用场景-实现页面间传值

    MUI框架-02-注意事项-适用场景-实现页面间传值 关于开发,我拷贝太多也没什么意义,就请查阅:官方文档:http://dev.dcloud.net.cn/mui/ui/ 快速入门 - 注意事项 有 ...

  7. Go语言基础之20--web编程框架之Gin框架

    一.Gin框架介绍 1.1 简介 A. 基于httprouter开发的web框架. http://github.com/julienschmidt/httprouter B. 提供Martini风格的 ...

  8. Gin 框架 - 安装和路由配置

    目录 概述 Gin 安装 路由配置 推荐阅读 概述 看下 Gin 框架的官方介绍: Gin 是一个用 Go (Golang) 编写的 web 框架. 它是一个类似于 martini 但拥有更好性能的 ...

  9. Gin 框架 - 使用 logrus 进行日志记录

    目录 概述 日志格式 Logrus 使用 推荐阅读 概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirup ...

随机推荐

  1. java深入浅出之数据结构

    1.整形数据 byte.short.int.long,分别是1248个字节的存储量,取值范围也是依次增大的,其中int是正负21亿多: long a = 1111222233334444L:记住后面要 ...

  2. Centos下部署Flask

    尝试在Centos6.5下部署Flask应用并成功,记录一下步骤,参数为什么这样配置还需要再研究uwsgi和Nginx才能回答. Python版本升级2.7 测试机器centos6.5默认自带的pyt ...

  3. 架构之CDN缓存

    CDN缓存 CDN主要解决将数据缓存到离用户最近的位置,一般缓存静态资源文件(页面,脚本,图片,视频,文件等).国内网络异常复杂,跨运营商的网络访问会很慢.为了解决跨运营商或各地用户访问问题,可以在重 ...

  4. SVN服务器搭建--Subversio与TortoiseSVN的配置安装(Windows)

    1.  Subversio和TortoiseSVN 简介 Subversio简介: Subversion是一个自由,开源的版本控制系统,可以随意地免费下载.修改.以及重新发布. 是一个通用系统,可以管 ...

  5. Python_网络攻击之端口

    #绝大多数成功的网络攻击都是以端口扫描开始的,在网络安全和黑客领域,端口扫描是经常用到的技术,可以探测指定主机上是否 #开放了指定端口,进一步判断主机是否运行了某些重要的网络服务,最终判断是否存在潜在 ...

  6. [ 搭建Redis本地服务器实践系列一 ] :图解CentOS7安装Redis

    上一章 [ 搭建Redis本地服务器实践系列 ] :序言 作为开场白介绍了下为什么要写这个系列,从这个章节我们就开始真正的进入正题,开始搭建我们本地的Redis服务器.那么关于Redis的基本概念,什 ...

  7. linux dialog详解(图形化shell)

    liunx 下的dialog 工具是一个可以和shell脚本配合使用的文本界面下的创建对话框的工具.每个对话框提供的输出有两种形式:   1.  将所有输出到stderr 输出,不显示到屏幕.   2 ...

  8. sqlserver聚合索引(clustered index) / 非聚合索引(nonclustered index)的理解

    1. 什么是聚合索引(clustered index) / 什么是非聚合索引(nonclustered index)? 可以把索引理解为一种特殊的目录.微软的SQL SERVER提供了两种索引:聚集索 ...

  9. Oracle-01:基础命令小结

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 记录一下我的Oracle学习之路,详细的安装教程忙完这俩天会认真总结一版 本次记录这次学习cmd基础命令 一, ...

  10. 监督学习——K邻近算法及数字识别实践

    1. KNN 算法 K-近邻(k-Nearest Neighbor,KNN)是分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一.该方法的思路是:如果一个样本在特征空间中的k个最相似( ...