【Go】Go Gin框架初识(一)

news2025/3/1 4:03:06

1. 什么是Gin框架

Gin框架:是一个由 Golang 语言开发的 web 框架,能够极大提高开发 web 应用的效率!

1.1 什么是web框架

web框架体系图(前后端不分离)如下图所示:

画板

从上图中我们可以发现一个Web框架最重要的一些组成部分:

  • HTTP解析/封装系统:解析HTTP请求以及将响应构造为HTTP请求等任务交由web框架来完成
  • 路由系统:将一个请求路由给某一个指定的处理器函数
  • 逻辑处理系统:是后端人员需要关注的重点区域,编写具体业务逻辑以及链接数据库
  • 模板引擎(前后端不分离):将数据嵌入到HTML模板中,构建动态页面

简单来说,web框架将一些繁琐且与业务逻辑无关的部分封装起来供开发者使用,这样开发人员只需要关注业务逻辑层的实现

1.2 web框架两种架构模式

常见的 web 架构模式有两种:

  1. 前后端不分离
  2. 前后端分离

上面已经介绍了前后端不分离的架构体系图,下图是前后端分离的架构图:

画板

可以看出主要区别在于后端没有了模板引擎,意味着HTML页面、图片等static静态资源全部都在前端服务器部署(如nginx),后端服务器只负责编写接口进行业务逻辑处理,然后将前端所需的数据暴露成接口返回!(不和页面打任何交道)

2. Gin框架

2.1 Gin框架如何安装

在Go 1.11之后引入了包管理机制,我们就可以使用go mod tidy一键将代码中所需导入的包从远程服务器下载到本地

package main

import "github.com/gin-gonic/gin"

func main() {
    // 获取引擎对象
    r := gin.Default()
    // 设置路由
    r.GET("/hello", func(c *gin.Context) {
        c.String(200, "Hello Gin")
    })
    // 启动
    r.Run(":8080")
}

编写完上述代码以后在控制台输入以下命令:

  1. go mod init gin_first:包管理初始化
  2. go mod tidy:下载所需依赖

看到上述信息就表明 gin 框架已经引入完毕!可以正式编写代码啦~

2.2 Gin框架的路由系统

2.2.1 基本使用

其实在 2.1 节我们已经初步使用过路由系统了

// 设置路由
r.GET("/hello", func(c *gin.Context) {
    c.String(200, "hello gin")
})

基本语法:r.操作方法(url, 处理器函数)

  • 操作方法:引擎对象基本支持所有的HTTP请求方法,比如GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS,以及Any(任何请求)、NoRoute(没有请求对应上时访问)
  • url:表示请求对应的路径
  • 处理器函数:表示请求路径为"/hello"时映射到该处理器函数进行执行

现在我们通过浏览器使用GET请求访问路径:http://localhost:8080/hello

2.2.2 路由分组

有时候我们希望对一个 url 路径做更统一化的管理,比如"/user/login"和"/user/register"实际上都是在"/user"路径下的子路由,这个时候就需要引入 路由分组

基本语法:子路由对象 := r.Group(根路由)

package main

import "github.com/gin-gonic/gin"

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置根路由
	userRouter := r.Group("/user")
	{
		userRouter.GET("/login", func(ctx *gin.Context) {
			ctx.String(200, "/user/login")
		})
		userRouter.GET("/register", func(ctx *gin.Context) {
			ctx.String(200, "/user/register")
		})
	}
	// 启动
	r.Run(":8080")
}

2.3 Gin框架获取参数

2.3.1 获取基本信息
2.3.1.1 获取请求方法

比如在Any请求内部想要知道具体请求方法可以使用:

基本语法:var method string = ctx.Request.Method

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc(ctx *gin.Context) {
	// 获取请求方法
	method := ctx.Request.Method
	fmt.Println("请求方法是:" + method)
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.Any("/method", handleFunc)
	// 启动
	r.Run(":8080")
}

代码运行结果:

2.3.1.2 获取请求URL

基本语法:var url string = ctx.Request.URL

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc(ctx *gin.Context) {
	// 获取请求URL
	var url string = ctx.Request.URL.String()
	fmt.Println("请求URL是:" + url)
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/url", handleFunc)
	// 启动
	r.Run(":8080")
}

代码运行结果:

2.3.1.3 获取远程IP地址

基本语法:

  • 方式一:var remoteAddr string = ctx.Request.RemoteAddr(包含端口)
  • 方式二:var remoteAddr string = ctx.ClientIP()(不包含端口)
package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc1(ctx *gin.Context) {
	// 获取远程ip
	var addr string = ctx.Request.RemoteAddr
	fmt.Println("远程ip:", addr)
	ctx.String(200, "request ok")
}

func handleFunc2(ctx *gin.Context) {
	// 获取远程ip
	var addr string = ctx.ClientIP()
	fmt.Println("远程ip:", addr)
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/addr1", handleFunc1)
	r.GET("/addr2", handleFunc2)
	// 启动
	r.Run(":8080")
}

代码运行结果:

2.3.1.4 获取请求头信息

本语法:var headerInfo string = ctx.GetHeader(键)

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc(ctx *gin.Context) {
	// 获取指定请求头
	var userAgent string = ctx.GetHeader("User-Agent")
	fmt.Println("Content-Type:", userAgent)
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/header", handleFunc)
	// 启动
	r.Run(":8080")
}

代码运行结果:

2.3.2 获取请求数据
2.3.2.1 获取查询字符串内容

通常来说使用 GET 请求发送请求都会将数据放置在查询字符串位置

  • 方式一 :var content string = ctx.Query(键)
  • 方式二:var content string = ctx.DefaultQuery(键, 缺省值),如果不存在则使用默认值填充
  • 方式三:value, ok := ctx.GetQuery(键),可以通过ok判断是否存在键
package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc1(ctx *gin.Context) {
	// 获取查询字符串数据
	var username = ctx.Query("username")
	var pwd = ctx.Query("pwd")
	fmt.Println("username:", username)
	fmt.Println("pwd:", pwd)
	ctx.String(200, "request ok")
}

func handleFunc2(ctx *gin.Context) {
	// 获取查询字符串数据
	var user = ctx.DefaultQuery("user", "wjj")
	fmt.Println("user:", user)
	ctx.String(200, "request ok")
}

func handleFunc3(ctx *gin.Context) {
	// 获取查询字符串数据
	user, exists := ctx.GetQuery("user")
	if exists {
		fmt.Println("键存在,值为:", user)
	} else {
		fmt.Println("键不存在!")
	}
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/queryString1", handleFunc1)
	r.GET("/queryString2", handleFunc2)
	r.GET("/queryString3", handleFunc3)
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.3.2.2 获取表单数据

前端使用 form表单 提交发送请求,此时Content-Typex-www-form-urlencoded可以使用PostForm获取表单内容

  • 方式一 :var content string = ctx.PostForm(键)
  • 方式二:var content string = ctx.DefaultPostForm(键, 缺省值),如果不存在则使用默认值填充
  • 方式三:value, ok := ctx.GetPostForm(键),可以通过ok判断是否存在键
package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

func handleFunc1(ctx *gin.Context) {
	// 获取查询字符串数据
	var username = ctx.PostForm("username")
	var pwd = ctx.PostForm("pwd")
	fmt.Println("username:", username)
	fmt.Println("pwd:", pwd)
	ctx.String(200, "request ok")
}

func handleFunc2(ctx *gin.Context) {
	// 获取查询字符串数据
	var user = ctx.DefaultPostForm("user", "wjj")
	fmt.Println("user:", user)
	ctx.String(200, "request ok")
}

func handleFunc3(ctx *gin.Context) {
	// 获取查询字符串数据
	user, exists := ctx.GetPostForm("user")
	if exists {
		fmt.Println("键存在,值为:", user)
	} else {
		fmt.Println("键不存在!")
	}
	ctx.String(200, "request ok")
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 加载HTML资源
	r.LoadHTMLGlob("templates/*")
	// 设置路由
	r.GET("/", func(ctx *gin.Context) {
		ctx.HTML(200, "index.html", nil)
	})
	r.POST("/postform1", handleFunc1)
	r.POST("/postform2", handleFunc2)
	r.POST("/postform3", handleFunc3)
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.3.2.3 获取JSON请求体数据

Go语言没有提供类似于 PostForm、Query 这样的API直接获取JSON数据,但是Go提供了ShouldBind函数,可以将 json 类型的数据自动映射到指定的结构体对象上

语法格式:ctx.ShouldBind(&结构体对象)

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
)

type Student struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.POST("/", func(ctx *gin.Context) {
		// 使用ShouldBind函数获取JSON数据
		var student Student
		err := ctx.ShouldBind(&student)
		if err != nil {
			fmt.Println(err)
			ctx.String(500, "解析错误")
		} else {
			fmt.Println(student)
			ctx.String(200, "request ok")
		}
	})
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.4 Gin框架返回响应

2.4.1 返回HTML页面

语法格式:ctx.HTML(响应状态码, 页面, 数据对象)

  • 响应状态码:对应的HTTP状态码
  • 页面:具体页面路径
  • 数据对象:与模板引擎相关(后续章节介绍)
package main

import "github.com/gin-gonic/gin"

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 加载模板文件
	r.LoadHTMLGlob("templates/*")
	// 设置路由
	r.GET("/", func(ctx *gin.Context) {
		// 返回首页
		ctx.HTML(202, "index.html", nil)
	})
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.4.2 返回String类型

语法格式:ctx.String(响应状态码, 格式化字符串)

  • 响应状态码:对应的HTTP状态码
  • 格式化字符串:具体返回的文本内容
package main

import "github.com/gin-gonic/gin"

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/", func(ctx *gin.Context) {
		// 返回sring类型
		ctx.String(200, "string 类型")
	})
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.4.3 返回JSON类型

语法格式:ctx.JSON(响应状态码, gin.H对象)

  • 响应状态码:对应的HTTP状态码
  • gin.H对象:具体返回JSON格式对象
package main

import "github.com/gin-gonic/gin"

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/", func(ctx *gin.Context) {
		// 返回json类型
		ctx.JSON(200, gin.H{
			"name": "wjj",
			"age":  21,
		})
	})
	// 启动
	r.Run(":8080")
}

程序运行结果:

2.4.4 返回XML类型

语法格式:ctx.XML(响应状态码, gin.H对象)

  • 响应状态码:对应的HTTP状态码
  • gin.H对象:具体返回XML格式对象
package main

import "github.com/gin-gonic/gin"

func main() {
	// 获取引擎对象
	r := gin.Default()
	// 设置路由
	r.GET("/", func(ctx *gin.Context) {
		ctx.XML(200, gin.H{
			"name": "wjj",
			"age":  21,
		})
	})
	// 启动
	r.Run(":8080")
}

程序运行结果:

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

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

相关文章

【深度学习】Windows系统Anaconda + CUDA + cuDNN + Pytorch环境配置

在做深度学习内容之前,为GPU配置anaconda CUDA cuDNN pytorch环境,在网络上参考了很多帖子,但pytorch的安装部分都有些问题或者比较复杂繁琐,这里总结了相对简单快速的配置方式 文章目录 AnacondaCUDAcuDNNpytorchtorchtorchau…

提供的 IP 地址 10.0.0.5 和子网掩码位 /26 来计算相关的网络信息

网络和IP地址计算器 https://www.sojson.com/convert/subnetmask.html提供的 IP 地址 10.0.0.5 和子网掩码位 /26 来计算相关的网络信息。 子网掩码转换 子网掩码 /26 的含义二进制表示:/26 表示前 26 位是网络部分,剩下的 6 位是主机部分。对应的子网掩码为 255…

js中的Object.defineProperty()详解

文章目录 一、Object.defineProperty()二、descriptor属性描述符2.1、数据描述符2.2、访问器描述符2.3、descriptor属性2.3.1、value2.3.2、writable2.3.3、enumerable (可遍历性)2.3.4、configurable (可配置性) 三、注意事项 一…

单细胞组学大模型(8)--- scGenePT,scGPT和GenePT的结合,实验数据和文本数据的交融模型

–https://doi.org/10.1101/2024.10.23.619972 研究团队和单位 Theofanis Karaletsos–Head Of AI - Science at Chan Zuckerberg Initiative (Chan Zuckerberg Initiative是扎克伯格和他妻子Chan成立的科研&教育机构) 研究简介 研究背景&…

微信原生小程序自定义封装组件(以导航navbar为例)

封装 topnav.js const App getApp(); Component({// 组件的属性列表properties: {pageName: String, //中间的titleshowNav: { //判断是否显示左上角的按钮 type: Boolean,value: true},showHome: { //判断是否显示左上角的home按钮type: Boolean,value: true},showLocat…

day06_Spark SQL

文章目录 day06_Spark SQL课程笔记一、今日课程内容二、DataFrame详解(掌握)5.清洗相关的API6.Spark SQL的Shuffle分区设置7.数据写出操作写出到文件写出到数据库 三、Spark SQL的综合案例(掌握)1、常见DSL代码整理2、电影分析案例…

HarmonyOS NEXT应用开发边学边玩,从零实现一影视APP(四、最近上映电影滚动展示及加载更多的实现)

在HarmonyOS NEXT开发环境中,我们可以使用多种组件和库来构建丰富且交互友好的应用。本文将展示如何使用HarmonyOS NEXT框架和nutpi/axios库,从零开始实现一个简单的影视APP的首页,主要关注最近上映电影的滚动展示及加载更多功能的实现。 安装…

快速、可靠且高性价比的定制IP模式提升芯片设计公司竞争力

作者:Karthik Gopal,SmartDV Technologies亚洲区总经理 智权半导体科技(厦门)有限公司总经理 无论是在出货量巨大的消费电子市场,还是针对特定应用的细分芯片市场,差异化芯片设计带来的定制化需求也在芯片…

基础入门-抓包技术HTTPS协议APP小程序PC应用Web证书信任转发联动

知识点: 1、抓包技术-Web应用-http/s-Burp&Yakit 2、抓包技术-APP应用-http/s-Burp&Yakit 3、抓包技术-PC端应用-http/s-Burp&Yakit 4、抓包技术-WX小程序-http/s-Burp&Yakit 5、抓包技术-软件联动-http/s-Proxifier 6、抓包技术-通用方案-http/s-R…

贪心算法详细讲解(沉淀中)

文章目录 1. 什么是贪心算法?(贪婪鼠目寸光)经典例题1.1.1 找零问题1.1.2最小路径和1.1.3 背包问题 2.贪心算法的特点2.1 证明例1 3.学习贪心的方向心得体会 1. 什么是贪心算法?(贪婪鼠目寸光) 贪心策略&a…

SQL面试题2:留存率问题

引言 场景介绍: 在互联网产品运营中,用户注册量和留存率是衡量产品吸引力和用户粘性的关键指标,直接影响产品的可持续发展和商业价值。通过分析这些数据,企业可以了解用户行为,优化产品策略,提升用户体验…

学会使用开源软件jclasslib 字节码文件的组成 详解

应用场景 1 应用场景 2 学习路线 以正确的姿势打开文件 字节码文件的组成 玩转字节码常用工具 以正确的姿势打开文件 开源软件 jclasslib github 地址 https://github.com/ingokegel/jclasslib 工具使用 字节码文件的组成 基本信息 常量池 字段 方法 属性 详解 魔数 主副版…

primitive 的 Appearance编写着色器材质

import { nextTick, onMounted, ref } from vue import * as Cesium from cesium import gsap from gsaponMounted(() > { ... })// 1、创建矩形几何体,Cesium.RectangleGeometry:几何体,Rectangle:矩形 let rectGeometry new…

详情页 路由传值

路由传值获取参数 渲染数据 主页面 <template><div class"km"><div v-for"item in items" :key"item.id"><div class"title-km" ><img :src"item.imageUrl" alt"Image" class"…

OpenCV基础:矩阵的创建、检索与赋值

本文主要是介绍如何使用numpy进行矩阵的创建&#xff0c;以及从矩阵中读取数据&#xff0c;修改矩阵数据。 创建矩阵 import numpy as npa np.array([1,2,3]) b np.array([[1,2,3],[4,5,6]]) #print(a) #print(b)# 创建全0数组 eros矩阵 c np.zeros((8,8), np.uint8) #prin…

解锁未来情感科技:AI 机器人 Ropet 搭载的前沿智能黑科技

2025年的国际消费电子产品展览会&#xff08;CES&#xff09;上&#xff0c;一只可爱的“毛绒玩具”成了全场焦点。 当然&#xff0c;这并不是一个单纯的玩偶&#xff0c;而是和《超能陆战队》的大白一样温暖的陪伴机器人。 相信有很多人和小编一样&#xff0c;当年看完《超能…

软件测试 —— Selenium常用函数

软件测试 —— Selenium常用函数 操作测试对象点击/提交对象 click()模拟按键输入 send_keys("")清除文本内容 clear() 模拟用户键盘行为 Keys包示例用法 获取文本信息 textget_attribute("属性名称") 获取当前页面标题 title获取当前页面的 url current_u…

【WEB】网络传输中的信息安全 - 加密、签名、数字证书与HTTPS

文章目录 1. 概述2. 网络传输安全2.1.什么是中间人攻击2.2. 加密和签名2.2.1.加密算法2.2.2.摘要2.2.3.签名 2.3.数字证书2.3.1.证书的使用2.3.2.根证书2.3.3.证书链 2.4.HTTPS 1. 概述 本篇主要是讲解讲一些安全相关的基本知识&#xff08;如加密、签名、证书等&#xff09;&…

服务器数据恢复—EMC存储POOL中数据卷被删除的数据恢复案例

服务器数据恢复环境&故障&#xff1a; EMC Unity 400存储连接了2台硬盘柜。2台硬盘柜上一共有21块硬盘&#xff08;520字节&#xff09;。21块盘组建了2组RAID6&#xff1a;一组有11块硬盘&#xff0c;一组有10块硬盘。 在存储运行过程中&#xff0c;管理员误操作删除了 2组…

python 轮廓 获取环形区域

目录 效果图&#xff1a; 代码&#xff1a; 效果图&#xff1a; 代码&#xff1a; import cv2 import numpy as np# 读取图像 image cv2.imread(rE:\project\jijia\tools_jijia\img_tools\ground_mask.jpg, cv2.IMREAD_GRAYSCALE) # 二值化图像 # 二值化图像 _, binary cv…