20 go语言(golang) - gin框架安装及使用(一)

news2025/3/1 16:18:55

一、简介

Gin是一个用Go语言编写的高性能Web框架,专注于构建快速、可靠的HTTP服务。它以其速度和简洁性而闻名,非常适合用于开发RESTful API。

  1. 高性能:Gin使用了httprouter进行路由管理,这是一个轻量级且非常快速的HTTP请求路由器。

  2. 中间件支持:Gin提供了一种简单的方法来创建和使用中间件,可以在请求处理过程中执行额外的操作,如日志记录、身份验证等。

  3. 错误管理:内置了错误处理机制,可以在请求生命周期内捕获并处理错误,确保应用程序稳定运行。

  4. JSON渲染:提供了便捷的方法来生成JSON响应,这对于构建API非常有用。

  5. 路由组:支持将路由组织成组,以便更好地管理复杂应用程序中的不同模块或版本控制。

  6. 优雅的API设计:提供了一套简洁易用的API,使得开发者可以快速上手并实现复杂功能。

二、安装

使用 go get 命令来下载并安装Gin包,详细参考官网文档:官方指引

go get -u github.com/gin-gonic/gin

三、使用

3.1 代码

下面是一个简单的示例程序,展示如何使用Gin创建一个Web服务器:

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"testing"
)

func Test1(t *testing.T) {
	// 创建一个带有Logger和Recovery中间件(用于日志记录和恢复崩溃)的默认Gin引擎。
	r := gin.Default()

	// 定义一个GET请求路由,当访问"/ping"时会调用指定匿名函数返回JSON响应。
	r.GET("/ping", func(c *gin.Context) {
		// 返回JSON格式的数据响应,其中`http.StatusOK`表示200状态码,而`gin.H{}`用于构造JSON对象。
		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})

	// 启动HTTP服务器,监听8080端口(如未指定端口,将默认为:8080)。
	r.Run(":8080")
}

3.2 运行程序

  • 在goland中右键运行

  • 打开浏览器或使用工具(如curl或Postman)访问 http://localhost:8080/ping后,JSON响应:

    {"message":"pong"}
    

四、组成

Gin 是一个用 Go 语言编写的高性能 HTTP Web 框架,特别适合用于构建微服务和快速开发 RESTful API。Gin 的组成主要包括以下几个核心部分:

  1. Router(路由器)

    • Gin 使用基于树结构的路由机制来处理 HTTP 请求。它支持动态路由参数、分组路由以及中间件。
    • 路由器负责将请求路径映射到相应的处理函数。
  2. Context(上下文)

    • gin.Context 是 Gin 中最重要的结构之一,它在请求生命周期内传递信息。
    • Context 提供了对请求和响应对象的访问,以及用于存储数据、设置状态码、返回 JSON 等方法。
  3. Middleware(中间件)

    • 中间件是可以在请求被最终处理之前或之后执行的一段代码,用于实现日志记录、错误恢复、认证等功能。
    • Gin 支持全局中间件和特定路由组或单个路由使用的中间件。
  4. Handlers(处理函数)

    • 处理函数是实际执行业务逻辑的位置,每个路由都会关联一个或多个处理函数。
    • 这些函数接收 gin.Context 参数,通过它们可以获取请求数据并生成响应。
  5. Error Handling(错误处理)

    • Gin 提供了一种机制来捕获和管理应用程序中的错误,可以通过 Context 的方法进行错误报告和恢复操作。
  6. Rendering and Responses(渲染与响应)

    • 支持多种格式的数据输出,包括 JSON、XML 和 HTML 渲染等,方便客户端消费不同类型的数据格式。
  7. Binding and Validation(绑定与验证)

    • 自动将 HTTP 请求中的数据绑定到结构体,并支持对输入数据进行验证,以确保其符合预期格式和规则。
  8. Templates (模板)

    • 虽然不是框架核心,但 Gin 支持集成 HTML 模板引擎,用于生成动态网页内容。

4.1 Router(路由器)

Gin 的路由器是其核心组件之一,负责将 HTTP 请求路径映射到相应的处理函数。它采用高效的树结构来管理路由,从而提高请求匹配速度。

4.1.1 基本路由

Gin 提供了简单的方法来定义基本的 HTTP 路由。例如,可以使用 GET, POST, PUT, DELETE 等方法来注册不同类型的请求。

func postTest(context *gin.Context) {
	context.JSON(http.StatusOK, gin.H{
		"message": "post_test_success",
	})
}

func Test2(t *testing.T) {
	r := gin.Default()

	r.POST("/post_test", postTest)

	r.Run()
}

请添加图片描述

4.1.2 动态路由参数

支持在 URL 中定义动态参数,允许从 URL 中提取变量。

func Test3(t *testing.T) {
	r := gin.Default()

	r.GET("/get_test/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.JSON(http.StatusOK, gin.H{
			"message": "hello:" + name,
		})
	})

	r.Run()

}

请添加图片描述

4.1.3 查询字符串和表单参数

可以通过上下文对象轻松获取查询字符串和表单数据。

func Test4(t *testing.T) {
	r := gin.Default()

	r.POST("/form_post", func(c *gin.Context) {
		name := c.PostForm("name")
		nickname := c.DefaultPostForm("nickname", "昵称")
		c.JSON(200, gin.H{
			"name":     name,
			"nickname": nickname,
		})
	})
	r.Run()
}

请添加图片描述

4.1.4 分组路由(Route Groups)

允许对一组具有共同前缀或中间件的路由进行分组管理。这有助于组织代码并应用共享行为。

func Test5(t *testing.T) {
	r := gin.Default()
	group := r.Group("/v1")
	handler := func(c *gin.Context) {
		println("调用了地址:" + c.Request.Host + c.Request.URL.Path)
	}
	{
		group.GET("/login", handler)
		group.GET("/submit", handler)
		group.GET("/listData", handler)
	}
	r.Run()
}

输出

调用了地址:localhost:8080/v1/login
[GIN] 2024/12/05 - 18:59:09 | 200 |      26.787µs |             ::1 | GET      "/v1/login"
调用了地址:localhost:8080/v1/submit
[GIN] 2024/12/05 - 18:59:24 | 200 |      11.511µs |             ::1 | GET      "/v1/submit"
调用了地址:localhost:8080/v1/listData
[GIN] 2024/12/05 - 18:59:31 | 200 |      10.746µs |             ::1 | GET      "/v1/listData"

4.1.5 优先级与冲突解决

Gin 的树形结构使得精确匹配路径比通配符路径优先级更高,因此 /v1/login 会比 /v1/:name 优先匹配。

func Test6(t *testing.T) {
	r := gin.Default()
	group := r.Group("/v1")
	handler := func(c *gin.Context) {
		println("调用了地址:" + c.Request.Host + c.Request.URL.Path)
	}
	handler2 := func(c *gin.Context) {
		name := c.Param("name")
		println("调用了地址:" + c.Request.Host + c.Request.URL.Path)
		c.JSON(http.StatusOK, gin.H{
			"message": "hello:" + name,
		})
	}
	{
		group.GET("/login", handler)
		group.GET("/:name", handler2)
	}
	r.Run()
}

4.2 Context(上下文)

gin.Context 是一个非常重要的结构体,它在每个请求的生命周期内被创建,并贯穿整个处理过程。上下文提供了丰富的方法和属性,用于简化请求数据的获取、响应生成以及中间件之间的数据共享。

4.2.1 请求数据访问

Context 提供了多种方法来访问 HTTP 请求的数据,包括路径参数、查询参数、表单数据和 JSON 数据等。

type MyStruct struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func Test7(t *testing.T) {
	r := gin.Default()
	r.GET("/:name", func(c *gin.Context) {

		// 获取路径参数
		name := c.Param("name")

		// 获取查询参数
		page := c.DefaultQuery("page", "0") // 带默认值

		// 获取表单参数
		message := c.PostForm("message")

		// 将请求body中的 JSON 数据 解析到结构体中
		var jsonData MyStruct
		if err := c.ShouldBindJSON(&jsonData); err != nil {
			c.JSON(400, gin.H{"error": err.Error()}) // 如果解析错误,则返回400报错
			return
		}

		println("调用了地址:" + c.Request.Host + c.Request.URL.Path)
		c.JSON(http.StatusOK, gin.H{
			"name":     name,
			"page":     page,
			"message":  message,
			"jsonData": jsonData,
		})
	})
	r.Run()
}

请添加图片描述

4.2.2 响应生成

上下文对象提供了一系列方法来构建 HTTP 响应,包括设置状态码、返回 JSON/XML/HTML 等。

func Test8(t *testing.T) {
	r := gin.Default()
	group := r.Group("/test_response")

	{
		group.GET("string", func(c *gin.Context) {
			// 返回字符串
			c.String(200, "string...")
		})

		group.GET("json", func(c *gin.Context) {
			// 返回json格式
			c.JSON(200, gin.H{
				"json": "json...",
			})
		})

    // 返回html页面,需要先加载模板
		r.LoadHTMLGlob("./html/*")
		group.GET("html", func(c *gin.Context) {
			c.HTML(200, "index.html", gin.H{
				"title": "这是个标题。。。",
			})
		})
	}

	r.Run()
}

项目目录下建html文件夹,里面新建文件index.html,内容为

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ .title }}</title>
</head>
<body>
    <h1>Welcome to {{ .title }}</h1>
</body>
</html>

4.2.3 状态码与头信息

可以通过上下文设置 HTTP 状态码和头信息。

  c.Status(200)

  c.Header("Content-Type", "application/json")  // 在使用 Gin 返回 JSON 响应时,c.JSON() 方法会自动将响应的内容类型设置为 application/json,所以通常不用手动设置

4.2.4 流控制与错误处理

支持流控制,比如终止请求链或跳过剩余中间件,还可以进行错误管理。

func Test9(t *testing.T) {

	r := gin.Default()
	r.GET("/test_error/:bool", func(c *gin.Context) {
		param := c.Param("bool")
		// 如果用户调用的是/test_error/true,则直接返回{ "error": "测试错误" }
		if param == "true" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "测试错误"})
			return
		}

		// 否则才正常返回
		c.JSON(200, gin.H{
			"success": "正常返回",
		})
	})

	r.Run()
}

4.2.5 键值存储(Set/Get)

上下文允许在不同处理中传递数据,可以使用键值对存储临时数据。

c.Set("mykey","value")

value,_:=c.Get ("mykey")

4.2.6 并发安全性

  • Gin 的 Context 是不支持跨 goroutine 使用的,因为它不是线程安全的。如果需要跨 goroutine 使用 Context 中的信息,应该提前将所需的数据提取出来。
  • 每个 HTTP 请求都会创建一个新的 Context 实例,该实例仅在处理该请求的过程中有效。一旦请求处理完毕,Gin 会回收这个 Context 对象以供将来的请求使用。因此,在另一个 goroutine 中持有对同一 Context 的引用可能导致不可预测的问题,因为原始请求可能已经结束。

4.3 Middleware(中间件)

中间件在处理请求的过程中起到拦截和处理的作用,可以在请求到达最终路由之前进行一些操作,比如日志记录、身份验证、跨域资源共享(CORS)、错误恢复等。

注!中间件的概念与Java中的切面(Aspect-Oriented Programming,AOP)在某些方面是像的!

  1. 定义:中间件是一个函数,它接收gin.Context作为参数,并通过调用Next()来执行下一个中间件或最终处理器。
  2. 链式调用:Gin中的中间件采用链式调用方式,多个中间件可以按顺序依次执行。
  3. 全局与局部:可以将中间件应用于整个应用程序,也可以仅限于特定路由。

4.3.1 默认中间件

Default引擎已经包含了两个默认中间件Logger()和Recovery()r := gin.Default()源码:

    // Default returns an Engine instance with the Logger and Recovery middleware already attached.
    func Default(opts ...OptionFunc) *Engine {
       debugPrintWARNINGDefault()
       engine := New()
       engine.Use(Logger(), Recovery()) // 配置了两个中间件
       return engine.With(opts...)
    }
  • gin.Logger()
    • 功能:这个中间件用于记录HTTP请求日志,包括请求的路径、方法、状态码、处理时间等信息。
    • 使用:通常用于开发和生产环境下的请求日志记录,帮助开发者了解应用程序的运行情况。
  • gin.Recovery()
    • 功能:这个中间件用于从panic(程序崩溃)中恢复,并返回500错误响应。它确保即使发生了未捕获的异常,服务器也不会崩溃。
    • 使用:建议在生产环境下始终启用,以提高应用程序的稳定性和可靠性。

4.3.1 全局中间件

全局中间件会对所有请求生效,通常用于通用功能,如日志记录或错误恢复。

通过r.Use()方法使用中间件:

// 使用Logger和Recovery两个默认提供的全局中间件
r.Use(gin.Logger())
r.Use(gin.Recovery())

4.3.2 路由组级别的中间件

可以将某些特定功能限制在某个路由组内,而不是整个应用程序。

func Test10(t *testing.T) {
	r := gin.Default()

	group := r.Group("/v1")

	// 对分组使用一个中间件
	group.Use(func(context *gin.Context) {
		fmt.Println("进入分组中间件")
	})
	
	group.GET("/group", func(c *gin.Context) {
		fmt.Println("group 返回json。。。")
		c.JSON(200, gin.H{
			"msg": "success!",
		})
	})

	r.GET("/v2", func(c *gin.Context) {
		fmt.Println("v2 返回json")
		c.JSON(200, gin.H{
			"msg": "success!",
		})
	})

	r.Run()

}

输出

进入分组中间件
group 返回json。。。
[GIN] 2024/12/12 - 14:57:16 | 200 |      28.996µs |             ::1 | GET      "/v1/group"
v2 返回json
[GIN] 2024/12/12 - 14:57:18 | 200 |      23.899µs |             ::1 | GET      "/v2"

4.3.3 实现自定义Middleware

自定义Middleware需要实现具体逻辑并返回gin.HandlerFunc类型。以下是一个简单示例:

func MyMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println("这是定义函数返回中间件的方式使用中间件")
	}
}

func Test11(t *testing.T) {

	r := gin.New()
	r.Use(MyMiddleware())

	r.Use(func(c *gin.Context) {
		fmt.Println("这是匿名函数的方式使用中间件")
	})

	r.GET("/test", func(c *gin.Context) {
		fmt.Println("正常返回")
	})

	r.Run()
}

输出

这是定义函数返回中间件的方式使用中间件
这是匿名函数的方式使用中间件
正常返回

为什么 Golang 知道这是一个 HandlerFunc?

Golang 是一种静态类型语言,它通过类型推断和接口匹配机制来判断某个对象是否实现了某个接口或符合某种类型。在 Gin 中,只要你的自定义方法符合上述签名,就会被自动识别为 HandlerFunc 类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2259526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

检查读取数据寄存器输出的多扇出

为使第二寄存器被 RAM 原语吸收&#xff0c;来自存储器阵列的数据输出位的扇出必须为 1 。这在下图中进行了说明。 检查地址 / 读取数据寄存器上的复位信号 不应复位存储器阵列。只有 RAM 的输出可以容许复位。复位必须是同步的&#xff0c;以便将输出寄存器推断到 RAM 基元…

rk3588-ubuntu22.04系统网关实现路由器功能:

rk3588-ubuntu22.04系统网关实现路由器功能&#xff1a; 场景需求描述&#xff1a; 需求背景&#xff1a; 场景一&#xff1a;通过网线eth0/(路由器wlan0)访问外网&#xff1a; 如果网关 和 设备所处的环境可以通过网线联网或者路由器联网&#xff0c;那么不需要将网关配置成…

Tomcat的下载和使用,配置控制台输出中文日志

目录 1. 简介2. 下载3. 使用3.1 文件夹展示3.1.1 控制台输出乱码 3.2 访问localhost:80803.3 访问静态资源 4. 总结 1. 简介 Tomcat&#xff0c;全称为Apache Tomcat&#xff0c;是一个开源的Web应用服务器和Servlet容器&#xff0c;由Apache软件基金会的Jakarta项目开发。它实…

【银河麒麟高级服务器操作系统】有关dd及cp测试差异的现象分析详解

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn dd现象 使用银河麒麟高级服务器操作系统执行两次…

【在Linux世界中追寻伟大的One Piece】自旋锁

目录 1 -> 概述 2 -> 原理 3 -> 优缺点及使用场景 3.1 -> 优点 3.2 -> 缺点 3.3 -> 使用场景 4 -> 纯软件自旋锁类似的原理实现 4.1 -> 结论 5 -> 样例代码 1 -> 概述 自旋锁是一种多线程同步机制&#xff0c;用于保护共享资源避免受并…

顺序表的使用,对数据的增删改查

主函数&#xff1a; 3.c #include "3.h"//头文件调用 SqlListptr sql_cerate()//创建顺序表函数 {SqlListptr ptr(SqlListptr)malloc(sizeof(SqlList));//在堆区申请连续的空间if(NULLptr){printf("创建失败\n");return NULL;//如果没有申请成功&#xff…

利用卷积神经网络进行手写数字的识别

数据集介绍 MNIST&#xff08;Modified National Institute of Standards and Technology&#xff09;数据集是一个广泛使用的手写数字识别数据集&#xff0c;常用于机器学习和计算机视觉领域中的分类任务。它包含了从0到9的手写数字样本&#xff0c;常用于训练和测试各种图像…

题解 - 取数排列

题目描述 取1到N共N个连续的数字&#xff08;1≤N≤9&#xff09;&#xff0c;组成每位数不重复的所有可能的N位数&#xff0c;按从小到大的顺序进行编号。当输入一个编号M时&#xff0c;就能打印出与该编号对应的那个N位数。例如&#xff0c;当N&#xff1d;3时&#xff0c;可…

如何在 ASP.NET Core 3.1 应用程序中使用 Log4Net

介绍 日志记录是应用程序的核心。它对于调试和故障排除以及应用程序的流畅性非常重要。 借助日志记录&#xff0c;我们可以对本地系统进行端到端的可视性&#xff0c;而对于基于云的系统&#xff0c;我们只能提供一小部分可视性。您可以将日志写入磁盘或数据库中的文件&#xf…

监控易监测对象及指标之:宝兰德中间件JMX监控指标解读

监控易作为一款全面的IT监控软件&#xff0c;能够为企业提供深入、细致的监控服务&#xff0c;确保企业IT系统的稳定运行。在本文中&#xff0c;我们将详细解读监控易针对宝兰德中间件JMX的监控指标&#xff0c;以帮助用户更好地理解和应用这些监控数据。 监测指标概览&#x…

Ubuntu 安装 Samba Server

在 Mac 上如何能够与Ubuntu 服务器共享文件夹&#xff0c;需要在 Ubuntu 上安装 Samba 文件服务器。本文将介绍如何在 Ubuntu 上安装 Samba 服务器从而达到以下目的&#xff1a; Mac 与 Ubuntu 共享文件通过用户名密码访问 安装 Samba 服务 sudo apt install samba修改配置文…

数字化招聘系统如何帮助企业实现招聘效率翻倍提升?

众所周知&#xff0c;传统的招聘方式已经难以满足现代企业对人才的需求&#xff0c;而数字化招聘系统的出现&#xff0c;为企业提供了全新的解决方案。通过数字化招聘系统&#xff0c;企业可以自动化处理繁琐的招聘流程&#xff0c;快速筛选合适的候选人&#xff0c;从而大幅提…

C语言数组和字符串笔记

C语言数组和字符串笔记 1. 数组及其相关概念 1.1 为什么需要使用数组&#xff1f; 数组是一个有序的、类型相同的数据集合。这些数据被称为数组的元素。每个数组都有一个名字&#xff0c;数组名代表数组的起始地址。数组的元素通过索引或下标访问&#xff0c;索引从0开始。 …

u-boot移植、配置、编译学习笔记【刚开始就中止了】

教程视频地址 https://www.bilibili.com/video/BV1L24y187cK 【这个视频中途停更了…原因是实际中需要去改u-boot的情况比较少】 使用的u-boot的源码 视频中使用的是 u-boot-2017.03 学习到这里&#xff0c;暂停u-boot的移植、配置、编译学习&#xff0c;原因是经过与老师…

回归任务与分类任务应用及评价指标

能源系统中的回归任务与分类任务应用及评价指标 一、回归任务应用1.1 能源系统中的回归任务应用1.1.1 能源消耗预测1.1.2 负荷预测1.1.3 电池健康状态估计&#xff08;SOH预测&#xff09;1.1.4 太阳能发电量预测1.1.5 风能发电量预测 1.2 回归任务中的评价指标1.2.1 RMSE&…

【树莓派4B】MindSpore lite 部署demo

一个demo&#xff0c;mindspore lite 部署在树莓派4B ubuntu22.04中&#xff0c;为后续操作开个门&#xff01; 环境 开发环境&#xff1a;wsl-ubuntu22.04分发版部署环境&#xff1a;树莓派4B&#xff0c;操作系统为ubuntu22.04mindspore lite版本&#xff1a;mindspore-li…

AI监控赋能健身馆与游泳馆全方位守护,提升安全效率

一、AI视频监控技术的崛起 随着人工智能技术的不断发展&#xff0c;AI视频监控正成为各行业保障安全、提升效率的关键工具。相比传统监控系统&#xff0c;AI技术赋予监控系统实时分析、智能识别和精准预警的能力&#xff0c;让“被动监视”转变为“主动防控”。 二、AI监控应用…

M|林中小屋

title: 林中小屋 The Cabin in the Woods time: 2024-12-13 周五 rating: 7 豆瓣: 7.6 上映时间: “2012” 类型: M恐怖 导演: 德鲁戈达德 Drew Goddard 主演: 克里斯汀康奈利 Kristen Connolly弗兰克朗茨 Fran Kranz 国家/地区: 美国 片长/分钟: 95分钟 M&#xff5…

Mysql中的sql语句怎么执行的?

1.连接MySQL 通过客户端使用TCP&#xff08;数据传输协议&#xff09;连接MySQL连接器&#xff0c;连接器接到请求后对它进行检验是否有权限&#xff0c;有就进行分配资源。&#xff08;这个过程不能超过8小时&#xff09; 2.成功连接(校验效验) 客户端发送sql语句&#xff…