概念

  1. 一个完整的系统可能包括鉴权认证、权限管理、安全检查、日志记录等多维度的系统支持。
  2. 中间件位与服务器和实际业务处理程序之间,其含义就相当于在请求和具体的业务处理逻辑之间增加某些操作,这种以额外增加的方式不会影响编码的效率,也不会侵入到框架中。

中间件的位置和角色示意图

自定义一个中间件

  • gin中间件的类型是函数,有两条标准
  1. func函数
  2. 返回值是HandlerFunc类型
  • 案例:定义一个log日志的中间件,打印path和Method
package main

import (
"fmt"
"github.com/gin-gonic/gin"
) func main() {
router := gin.New() // 全局使用自定义的中间件
router.Use(Logger()) router.GET("/hello", HelloHandle)
// 单个接口使用自定义的中间件
router.GET("/index", RemoteAddr(), IndexHandle) router.Run(":8000")
}
func Logger() gin.HandlerFunc {
// 打印请求路径和方法的中间件
return func(ctx *gin.Context) {
fmt.Println(ctx.FullPath(), ctx.Request.Method)
}
}
func RemoteAddr() gin.HandlerFunc {
// 打印远程地址的中间件
return func(context *gin.Context) {
fmt.Println(context.Request.RemoteAddr)
}
}
func HelloHandle(ctx *gin.Context) {
ctx.Writer.Write([]byte("hello world!"))
}
func IndexHandle(ctx *gin.Context) {
ctx.Writer.Write([]byte("hello index!"))
}

context.Next函数

  • contentx.Next函数可以将中间件代码的执行顺序一分为二,Next函数之前的代码在请求处理之前执行,当执行到Next函数时会中断向下执行,去执行具体的业务逻辑代码,当业务逻辑代码执行完成后,在继续执行Next函数后面的代码。
  • 案例
package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
) func main() {
router := gin.Default() // 全局使用自定义的中间件
router.Use(Logger()) router.GET("/hello", HelloHandle)
// 单个接口使用自定义的中间件
router.GET("/index", RemoteAddr(), IndexHandle) router.Run(":8000")
}
func Logger() gin.HandlerFunc {
// 打印请求路径和方法的中间件
return func(ctx *gin.Context) {
fmt.Println(ctx.FullPath(), ctx.Request.Method)
fmt.Println("状态码", ctx.Writer.Status())
ctx.Next()
fmt.Println("状态码", ctx.Writer.Status())
}
}
func RemoteAddr() gin.HandlerFunc {
// 打印远程地址的中间件
return func(context *gin.Context) {
fmt.Println(context.Request.RemoteAddr) // 中断执行,去执行接口业务代码,接口业务执行完毕后在回来执行context.Next()后面的代码
context.Next() status := context.Writer.Status()
fmt.Println("状态码:", status)
}
}
func HelloHandle(ctx *gin.Context) {
ctx.String(http.StatusNotFound, "404 not found")
fmt.Println("hello接口执行完了")
}
func IndexHandle(ctx *gin.Context) {
fmt.Println("index函数执行了")
ctx.Writer.Write([]byte("hello index!"))
}

gin框架中中间件的编写与使用的更多相关文章

  1. 在gin框架中使用JWT

    在gin框架中使用JWT JWT全称JSON Web Token是一种跨域认证解决方案,属于一个开放的标准,它规定了一种Token实现方式,目前多用于前后端分离项目和OAuth2.0业务场景下. 什么 ...

  2. golang gin框架中实现一个简单的不是特别精确的秒级限流器

    起因 看了两篇关于golang中限流器的帖子: Gin 开发实践:如何实现限流中间件 常用限流策略--漏桶与令牌桶介绍 我照着用,居然没效果-- 时间有限没有深究.这实在是一个很简单的功能,我的需求是 ...

  3. gin框架中的路由

    基本路由 gin框架中采用的路由库是基于httrouter做的 地址为:https://github.com/julienschmidt/httprouter httprouter路由库 点击查看代码 ...

  4. gin框架中请求路由组的使用

    1. gin框架中可以使用路由组来实现对路由的分类 package main import "github.com/gin-gonic/gin" func main() { rou ...

  5. gin框架中的中间件

    全局中间件 所有请求都经过此中间件 中间件中设置值 func MiddleWare() gin.HandlerFunc { return func(context *gin.Context) { t ...

  6. Gin框架中文文档

    Gin 是一个 go 写的 web 框架,具有高性能的优点.官方地址:https://github.com/gin-gonic/gin 带目录请移步 http://xf.shuangdeyu.com/ ...

  7. 【解决了一个小问题】gin框架中出现如下错误:"[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500"

    POST到数据到一条gin框架的接口后,客户端收到400错误,并且返回了业务中返回的"decode json fail". 关键代码是: func report(c *gin.Co ...

  8. golang gin框架中实现大文件的流式上传

    一般来说,通过c.Request.FormFile()获取文件的时候,所有内容都全部读到了内存.如果是个巨大的文件,则可能内存会爆掉:且,有的时候我们需要一边上传一边处理. 以下的代码实现了大文件流式 ...

  9. gin框架中使用jwt

    生成解析token 如今有很多将身份验证内置到API中的方法 -JSON Web令牌只是其中之一.JSON Web令牌(JWT)作为令牌系统而不是在每次请求时都发送用户名和密码,因此比其他方法(如基本 ...

随机推荐

  1. 制作一个文档同步工具,自动同步到gitee中。。。

    之所以要做这个工具是为了让自己可以随时用电脑时能记录日常工作或生活.一般只需要简单记录下就行了.这样我在家里的和公司里的记录都能同步看到. 这样后期整理的时候看到几个关键词就能想起来具体的事情,有的也 ...

  2. 一篇文章讲明白vue3的script setup,拥抱组合式API!

    引言 vue3除了Composition API是一个亮点之外,尤大大又给我们带来了一个全新的玩意 -- script setup,对于setup大家相信都不陌生,而对于script setup有些同 ...

  3. centos7使用Dockerfile运行mysql库并初始化数据

    Dockerfile文件(文件名一定要这个) FROM mysql:5.7 WORKDIR /docker-entrypoint-initdb.d ENV LANG=C.UTF-8 ADD test. ...

  4. Spring核心原理之 IoC容器中那些鲜为人知的细节(3)

    本文节选自<Spring 5核心原理> Spring IoC容器还有一些高级特性,如使用lazy-init属性对Bean预初始化.使用FactoryBean产生或者修饰Bean对象的生成. ...

  5. 『与善仁』Appium基础 — 27、模拟手势点击坐标

    目录 1.模拟手势点击坐标 2.tap()用法 3.练习 4.弊端 1.模拟手势点击坐标 在定位元素的时候,你使出了十八班武艺还是定位不到,怎么办呢?(面试经常会问) 那就拿出绝招:点击元素所在位置的 ...

  6. GCD (hdu 5726)

    GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  7. Bayesian Optimization with a Finite Budget: An Approximate Dynamic Programming Approach

    目录 概 主要内容 Lam R, Willcox K, Wolpert D H, et al. Bayesian Optimization with a Finite Budget: An Appro ...

  8. Java EE数据持久化框架 • 【第1章 MyBatis入门】

    全部章节   >>>> 本章目录 1.1 初识MyBatis 1.1.1 持久化技术介绍 1.1.2 MyBatis简介 1.1.2 Mybatis优点 1.1.3 利用Mav ...

  9. Java初学者作业——编写JAVA程序,计算跳水运动员本次动作的最终得分。

    返回本章节 返回作业目录 需求说明: 编写JAVA程序,计算跳水运动员本次动作的最终得分. 规则如下: 在跳水比赛中,共有六位裁判对运动员所完成的动作进行评分,每位裁判的评分在0-10之间,运动员最终 ...

  10. 基于GO语言的PBFT共识算法

    最近采用GO语言实现了一个PBFT共识算法的demo,主要用于展示算法的核心逻辑 github地址:https://github.com/w3liu/consensus/tree/master/pbf ...