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

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")
}

程序运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP协议簇及封装与解封装

TCP/IP协议簇 现如今用的参考模型TCP/IP 是一个协议簇,它组建了整个互联网 最主要的是TCP/IP 和这两个协议,所以起名为TCP/IP TCP/IP模型 TCP/IP标准模型——四层 TCP/IP对等模型——五层 数据链路层分为两个子层: LLC子层:逻辑…

《基于卷积神经网络的星图弱小目标检测》论文精读

Dim small target detection based on convolutinal neural network in star image 摘要 由于低信噪比目标和复杂背景,星图中弱小目标的检测是一项具有挑战性的任务。本文提出了一种深度学习方法,用于在背景不均匀和不同类型的噪声下检测单帧星图中的弱…

如何选择Ubuntu版本

一、为什么要选择Ubuntu系统? CentOS官方已全面停止维护CentOS Linux项目 。具体来说,CentOS 8已于2021年12月31日停止维护,而CentOS 7则在2024年6月30日结束了生命周期 。这意味着这些版本不再接收官方的安全更新、bug修复或技术支持 二、…

计算机视觉算法实战——视频分析(Video Analysis)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​​ ​​​​​​​​​​​​ ​​​​​ 视频分析是计算机视觉中的一个重要领域,旨在从视频数据中提取有用的信息&…

O2O同城系统架构与功能分析

2015工作至今,10年资深全栈工程师,CTO,擅长带团队、攻克各种技术难题、研发各类软件产品,我的代码态度:代码虐我千百遍,我待代码如初恋,我的工作态度:极致,责任&#xff…

讲一下ZooKeeper的持久化机制?

大家好,我是锋哥。今天分享关于【讲一下ZooKeeper的持久化机制?】面试题。希望对大家有帮助; 讲一下ZooKeeper的持久化机制? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 ZooKeeper 是一个开源的分布式协调服务&…

C++ 文字识别OCR

一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…

数据库(MySQL)练习

数据库(MySQL)练习 一、练习1.15练习1.16练习 二、注意事项2.1 第四天 一、练习 1.15练习 win11安装配置MySQL超详细教程: https://baijiahao.baidu.com/s?id1786910666566008458&wfrspider&forpc 准备工作: mysql -uroot -p #以…

【HTML+CSS+JS+VUE】web前端教程-35-字体图标

优点: 轻量性:加载速度快,减少http请求 灵活性:可以利用CSS设置大小颜色等 兼容性:网页字体支持所有现代浏览器,包括IE低版本 使用字体图标: 1、注册账户并登录 2、选取图标或搜索图标 3、添加购物车 4、下载代码 5、选择font-class引用 iconfont Logo:https://www.ic…

YOLOv8模型改进 第二十九讲 添加可学习小波变换节点 Learnable Wavelet Transform Node 提高小目标检测能力,增强细节特征

在图像去模糊领域,多尺度架构虽被广泛应用,但存在固有缺陷。在渐进恢复过程中,由于底层空间分辨率小,向上传递的特征语义精确但空间模糊,导致多尺度网络在空间细节恢复能力上受限。为提升高频细节部分的恢复质量&#…

数据库基础实验1(创建表,设置外键,检查,不为空,主键等约束)安装mysql详细步骤

安装MySQL详细步骤 1. 下载 MySQL 安装程序 访问 MySQL 官方网站:MySQL Downloads。在下载页面,选择 "MySQL Community (GPL) Downloads"。在 "MySQL Community Server" 部分,根据你的操作系统(Windows&…

CSRF(跨站请求伪造)深度解析

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

详解如何自定义 Android Dex VMP 保护壳

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 前言 Android Dex VMP(Virtual Machine Protection,虚拟机保护)壳是一种常见的应用保护技术,主要用于保护 And…

rabbitmqp安装延迟队列

在RabbitMQ中,延迟队列是一种特殊的队列类型。当消息被发送到此类队列后,不会立即投递给消费者,而是会等待预设的一段时间,待延迟期满后才进行投递。这种队列在多种场景下都极具价值,比如可用于处理需要在特定时间触发…

向量数据库如何助力Text2SQL处理高基数类别数据

01. 导语 Agent工作流和 LLMs (大语言模型)的出现,让我们能够以自然语言交互的模式执行复杂的SQL查询,并彻底改变Text2SQL系统的运行方式。其典型代表是如何处理High-Cardinality Categorical Data (高基数类别数据&am…

Docker实践:部署Docker管理工具DockerUI

Docker实践:部署Docker管理工具DockerUI 前言一、DockerUI介绍1.1 DockerUI概述1.2 镜像说明 二、检查本地Docker环境三、拉取DockerUI镜像四、创建DockerUI容器五、访问DockerUI六、DockerUI的基本使用6.1 查询宿主机容器情况6.2 查询Docker镜像列表6.3 查看容器配…

【excel】VBA股票数据获取(搜狐股票)

文章目录 一、序二、excel 自动刷新股票数据三、付费获取 一、序 我其实不会 excel 的函数和 visual basic。因为都可以用matlab和python完成。 今天用了下VBA,还挺不错的。分享下。 上传写了个matlab获取股票数据的,是雅虎财经的。这次是搜狐股票的数…

解锁企业数据管理统一身份认证难题,EasyMR助力企业敏捷提效

在数字经济迅猛发展的当下,企业数据量正以令人惊叹的速度持续增长。据IDC研究显示,至2025年,全球数据总量预计将超175 ZB。数据的爆发式增长对企业而言,既是机遇,更是巨大挑战。 如今,大数据已然成为企业决…

IntelliJ IDEA Type Hierarchy Scope Pattern 学习指南

IntelliJ IDEA Type Hierarchy Scope Pattern 学习指南 什么是 Type Hierarchy? Type Hierarchy 是 IntelliJ IDEA 提供的一个工具,允许开发者查看某个类的继承关系及其实现的接口结构。它是理解类关系的重要工具,尤其在处理复杂的继承体系…

ukui-quick 计数器

作品简介 使用ukui-quick框架进行开发,实现了在任务栏中计数器的插件,方便用户的日常使用。 技术架构 用于实现一个具有点击计数功能的QML应用程序。这个架构将包括C后端和QML前端,通过Qt的信号和属性绑定机制进行交互。 实现过程 开发环…