Go gin框架(详细版)
目录
0. 为什么会有Go
1. 环境搭建
2. 单-请求&&返回-样例
3. RESTful API
3.1 首先什么是RESTful API
3.2 Gin框架支持RESTful API的开发
4. 返回前端代码
go.main
index.html
5. 添加静态文件
main.go 改动的地方
index.html 改动的地方
style.css 改动的地方
common.js 改动的地方
6. 获取请求中的参数
6.1 传统的传参
6.2 RESTful API 方式传参与接收
6.3 前端传递Json数据给后端
6.4 前端返回的是表单
在index.html添加表单
在main.go里面添加特定请求的放法
7. 关于重定向
7.1 重定向到网页
main.go
7.2 404
main.go
添加404.html,让重定向去跳转
7.3 路由组
main.go
8. 中间件(java里面的拦截器)
9. 总代码
main.go
templates/index.html
static/css
style.css
common.css
0. 为什么会有Go

1. 环境搭建
初始项目
go mod init 目前文件夹名
下载:
go get -u github.com/gin-gonic/gin
2. 单-请求&&返回-样例
这样我们的服务就可以跑起来了哈
此时提供给了前端GET请求的/hello路由,GET后面的函数就是我们对此请求的处理(返回给前端)

package main//导入gin
import ("github.com/gin-gonic/gin"
)func main(){//创建一个服务ginServer := gin.Default()//访问地址,处理我们的请求 Request ResponseginServer.GET("/hello", func(context/*理解为我们上下文接收请求或者响应数据*/ *gin.Context) {/*我们所有的信息使用gin的默认对象包裹*/context.JSON(200,gin.H{"message":"hello world"})})//服务器端口ginServer.Run(":9090")/*默认是8080*/
}

(这个插件是之前提过的哈)
或者直接访问

3. RESTful API
然后我们现在写一个 RESTful API
3.1 首先什么是RESTful API
以前写网站:
比如查询用户就是:get /user
创建一个用户就是:post /create_user
又或者更新用户就是:post /update_user
又或者删除用户就是:post /delete_user
RESTful API 就是通过不同的请求执行不同的功能,以前我们是通过url和请求来隔离,现在我们可以通过四种方式来隔离,比如:
查询用户:get /user
提交用户:post /user
修改用户:put /user(这个就变了,不是post)
删除用户:delete /user
就是我们同一个请求(/user)用不同的方式(get post put),会执行不同的方法,这就是RESTful API
3.2 Gin框架支持RESTful API的开发
所以我们的代码就可以变成:
我们就发现 Go语言+Gin框架 去开发 RESTful API 是非常简单的

(但是注意,有这些方法之后,浏览器就测试不了了,因为浏览器只会使用GET方法,就需要用到上面的工具了)
然后我们现在重新(不要上一个图的东西)写一个请求然后返回前端页面的代码
4. 返回前端代码
go.main
package main//导入gin
import ("github.com/gin-gonic/gin"
)func main() {//创建一个服务ginServer := gin.Default()//加载前端页面//加载所有的html文件,还有一个是加载特定的文件LoadHTMLFiles//就是ginServer.LoadHTMLFiles("templates/index.html")ginServer.LoadHTMLGlob("templates/*")//访问地址,处理我们的请求 Request ResponseginServer.GET("/index", func(context *gin.Context) {//context.JSON(200,gin.H{"message":"hello world"}) 返回json数据//可以HTML查看定义,第一个是状态码,第二个是返回的文件名,第三个是想给文件传的参数//数据传送都是用框架的.H方法(map集合),H的定义也就是key value,所以可以传多个参数context.HTML(200, "index.html", gin.H{"msg": "这是后端传来的数据",}) //返回html数据})//服务器端口ginServer.Run(":9090") /*默认是8080*/
}
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>个人主页</title>
</head><body><h1>欢迎来到我的个人主页</h1>
获取后端的数据为:
{{.msg}}
</body>
</html>

5. 添加静态文件
现在我们还可以在网站里面加一些静态文件
.
├── go.mod
├── go.sum
├── main.go
├── static
│ ├── css
│ │ └── style.css
│ └── js
│ └── common.js
└── templates
└── index.html
main.go 改动的地方

index.html 改动的地方

style.css 改动的地方

common.js 改动的地方



6. 获取请求中的参数
6.1 传统的传参


6.2 RESTful API 方式传参与接收


6.3 前端传递Json数据给后端


6.4 前端返回的是表单
在index.html添加表单
在main.go里面添加特定请求的放法



7. 关于重定向
注意重定向的状态码不是200
7.1 重定向到网页
main.go


7.2 404
main.go

添加404.html,让重定向去跳转


7.3 路由组
路由组就是我们可以统一管理路由,比如跟/user相关的所有路由,我们都放在这个里面
main.go


8. 中间件(java里面的拦截器)
中间件就是比如前端发送一个请求到/user/add,然后这个请求就到我们后端来处理了,但是我现在想这个请求没有到我的程序之前加一道防火墙,在拦截的地方预处理这个请求,这就是go的中间件。(一般这个预处理我们就会进行比如登录的验证,授权,分页,耗时统计...)
我们现在自己来实现一个中间件:

然后我们来使用:

现在我们在这里多加了一个中间件的函数,让我们调用这个方法的时候,先让myHandler去处理




如果中间件进行拦截,就会返回这个

9. 总代码

main.go
package main//导入gin
import ("encoding/json""log""net/http""github.com/gin-gonic/gin"
)func myHandler() gin.HandlerFunc {return func(context *gin.Context) {//通过自定义的中间件,设置的值,后续处理只要调用了这个中间件//的都可以拿到这个值context.Set("usersesion", "userid-1")//拦截器无非就两个方法,一个是放过一个是拦截if true {context.Next() //放行}context.Abort() //阻止}}func main() {//创建一个服务ginServer := gin.Default()//注册中间件//如果没有指定特定请求方法,那么就是所有方法都使用,指定了就是特定的ginServer.Use(myHandler())//加载前端页面//加载所有的html文件,还有一个是加载特定的文件LoadHTMLFiles//就是ginServer.LoadHTMLFiles("templates/index.html")ginServer.LoadHTMLGlob("templates/*")//跳转到这里,然后加载资源文件 static是前端文件夹,./static是文件夹的路径ginServer.Static("/static", "./static")//访问地址,处理我们的请求 Request ResponseginServer.GET("/index", func(context *gin.Context) {//context.JSON(200,gin.H{"message":"hello world"}) 返回json数据//可以HTML查看定义,第一个是状态码,第二个是返回的文件名,第三个是想给文件传的参数//数据传送都是用框架的.H方法(map集合),H的定义也就是key value,所以可以传多个参数context.HTML(200, "index.html", gin.H{"msg": "这是后端传来的数据",}) //返回html数据})//获取请求中的参数//传统的传参方法:url?userid=xxx&username=xxx//请求-处理请求的函数,这个格式是固定的ginServer.GET("/user/info", myHandler(), func(context *gin.Context) {//加入中间件之后,开始说了调用的函数都可以取到中间件的值,现在我们取他//看源码返回的是any,我们转成stringusersesion := context.MustGet("usersesion").(string)log.Println("==============>", usersesion)userid := context.Query("userid")username := context.Query("username")context.JSON(http.StatusOK, gin.H{"userid": userid,"username": username,})})//RESTful传参方法:/url/info/1/xxxginServer.GET("/user/info/:userid/:username", func(context *gin.Context) {userid := context.Param("userid")username := context.Param("username")context.JSON(http.StatusOK, gin.H{"userid": userid,"username": username,})})//前端给后端传递 json数据ginServer.POST("/json", func(context *gin.Context) {//从 request.body中获取json数据//[]byte是字节切片,是一个二进制数据,可以理解为一个字符串b, _ := context.GetRawData()var m map[string]interface{}//切片b转换成map_ = json.Unmarshal(b, &m)context.JSON(http.StatusOK, m)})ginServer.POST("/user/add", func(context *gin.Context) {username := context.PostForm("username")password := context.PostForm("password")context.JSON(http.StatusOK, gin.H{"msg": "ok","username": username,"password": password,})})//关于重定向ginServer.GET("/redirect", func(context *gin.Context) {//重定向到百度context.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")})//404 就是 NoRouteginServer.NoRoute(func(context *gin.Context) {context.HTML(http.StatusNotFound, "404.html", nil)})userGroup := ginServer.Group("/user"){//我们去网页访问的时候,就想当关于 /user/listuserGroup.GET("/list", func(context *gin.Context) {context.JSON(http.StatusOK, gin.H{"msg": "获取用户列表",})//我们去网页访问的时候,就想当关于 /user/infouserGroup.POST("/info", func(context *gin.Context) {context.JSON(http.StatusOK, gin.H{"msg": "获取用户信息",})})})}//服务器端口ginServer.Run(":9090") /*默认是8080*/
}
templates/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>个人主页</title><!--引入静态文件,css是link--><link rel="stylesheet" href="/static/css/style.css"><!--引入静态文件,js是script--><script src="/static/js/common.js"></script><!--但是并不是引用了就能直接用,现在跳转到main.go中--></head><body><h1>欢迎来到我的个人主页</h1>
获取后端的数据为:
{{.msg}}<!--这就是个提交表单,提交之后就会让后端处理这个请求-->>
<form action="/user/add" method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<p><input type="submit" value="提交"></p>
</form></body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>404 Not Found</title><style>body {font-family: Arial, sans-serif;text-align: center;background-color: #f0f0f0;}h1 {font-size: 6em;color: #333;margin-top: 20vh;}p {font-size: 1.5em;color: #666;}a {color: #007bff;text-decoration: none;}</style>
</head>
<body><h1>404</h1><p>Oops! The page you're looking for could not be found.</p><p>Go back to <a href="/">homepage</a>.</p>
</body>
</html>
static/css
style.css
body{background:aqua;/*让背景颜色变成蓝色*/
}
common.css
狂神YYDS!!!
创作不易,希望读者三连支持 💖
赠人玫瑰,手有余香 💖
相关文章:
Go gin框架(详细版)
目录 0. 为什么会有Go 1. 环境搭建 2. 单-请求&&返回-样例 3. RESTful API 3.1 首先什么是RESTful API 3.2 Gin框架支持RESTful API的开发 4. 返回前端代码 go.main index.html 5. 添加静态文件 main.go 改动的地方 index.html 改动的地方 style.css 改动…...
Git分布式版本控制系统——Git常用命令(二)
五、Git常用命令————分支操作 同一个仓库可以有多个分支,各个分支相互独立,互不干扰 分支的相关命令,具体如下: git branch 查看分支 git branch [name] 创建分支&#x…...
LeetCode 59.螺旋矩阵II
LeetCode 59.螺旋矩阵II 1、题目 力扣题目链接:59. 螺旋矩阵 II - 力扣(LeetCode) 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1࿱…...
03-JAVA设计模式-适配器模式
适配器模式 设么是适配器模式 它属于结构型模式,主要用于将一个类的接口转换成客户端所期望的另一种接口,从而使得原本由于接口不兼容而无法协同工作的类能够一起工作。 适配器模式主要解决的是不兼容接口的问题。在软件开发中,经常会有这…...
MVVM架构模式
目录 MVVM 数据绑定方式 实现方式 Model View ViewModel 数据绑定方式 vue:: 数据劫持和发布-订阅模式: Object.defineProperty() 方法来劫持(监控)各属性的 getter 、setter ,并在数据(对…...
leetcode2924--找到冠军II
1. 题意 给定一个有向无环图,方向表示胜负关系;求最后胜出的人。 2. 题解 将所有人标记为胜者,统计出度去掉对应胜者标记; 最后统计胜者数目,是否大于1,若大于1,则没有胜者,否则…...
嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记13:RTC实时时钟
系列文章目录 嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台 嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装 嵌入式|蓝桥杯STM32G431(…...
统一用安卓Studio修改项目包名
可以逃跑,可以哭泣,但不可以放弃 --《鬼灭之刃》 修改项目包名 1)选中项目中药修改的包名: 2)目结构显示方式,取消 Compact Middle Packages 选项; 3)右键要修改的包名,选择 Refactor —— Re…...
Spring Cloud Gateway详细介绍以及实现动态路由
一. 简介 Spring Cloud Gateway This project provides a libraries for building an API Gateway on top of Spring WebFlux or Spring WebMVC. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to …...
transformer上手(6)—— 微调预训练模型
1 加载数据集 以同义句判断任务为例(每次输入两个句子,判断它们是否为同义句),构建我们的第一个 Transformers 模型。我们选择蚂蚁金融语义相似度数据集 AFQMC 作为语料,它提供了官方的数据划分,训练集 / …...
web前端框架设计第四课-条件判断与列表渲染
web前端框架设计第四课-条件判断与列表渲染 一.预习笔记 1.条件判断 1-1:v-if指令:根据表达式的值来判断是否输出DOM元素 1-2:template中使用v-if 1-3:v-else 1-4:v-else-if 1-5:v-show(不支…...
计算机网络:数据链路层 - CSMA/CD协议
计算机网络:数据链路层 - CSMA/CD协议 媒体接入控制CSMA/CD协议截断二进制指数退避算法帧长与帧间间隔信道利用率 媒体接入控制 如图所示,这是一根同轴电缆,有多台主机连接到这根同轴电缆上,他们共享这根传输媒体,形成…...
力扣LeetCode138. 复制带随机指针的链表 两种解法(C语言实现)
目录 题目链接 题目分析 题目定位: 解题思路 解题思路1(粗暴但是复杂度高) 解题思路2(巧妙并且复杂度低) 题目链接 138. 复制带随机指针的链表https://leetcode-cn.com/problems/copy-list-with-random-pointer/ …...
强大的压缩和解压缩工具 Keka for Mac
Keka for Mac是一款功能强大的压缩和解压缩工具,专为Mac用户设计。它支持多种压缩格式,包括7z、Zip、Tar、Gzip和Bzip2等,无论是发送电子邮件、备份文件还是节省磁盘空间,Keka都能轻松满足用户需求。 这款软件的操作简单直观&…...
论文速读:Do Generated Data Always Help Contrastive Learning?
在对比学习领域,最近很多研究利用高质量生成模型来提升对比学习 给定一个未标记的数据集,在其上训练一个生成模型来生成大量的合成样本,然后在真实数据和生成数据的组合上执行对比学习这种使用生成数据的最简单方式被称为“数据膨胀”这与数据…...
华为欧拉系统(openEuler-22.03)安装深信服EasyConnect软件(图文详解)
欧拉镜像下载安装 iso镜像官网下载地址 选择最小化安装,标准模式 换华为镜像源 更换华为镜像站,加速下载: sed -i "s#http://repo.openeuler.org#https://mirrors.huaweicloud.com/openeuler#g" /etc/yum.repos.d/openEuler.r…...
git commit --amend用法
一、git commit --amend 修改提交信息:您可以使用 git commit --amend 命令来修改最新提交的提交信息。执行该命令后,Git 将会打开文本编辑器(通常是的默认文本编辑器),以便编辑提交信息。完成编辑后保存并关闭编辑器…...
分布式系统:缓存与数据库一致性问题
前言 缓存设计是应用系统设计中重要的一环,是通过空间换取时间的一种策略,达到高性能访问数据的目的;但是缓存的数据并不是时刻存在内存中,当数据发生变化时,如何与数据库中的数据保持一致,以满足业务系统…...
JavaEE企业开发新技术5
目录 2.18 综合应用-1 2.19 综合应用-2 2.20 综合应用-3 2.21 综合应用-4 2.22 综合应用-5 Synchronized : 2.18 综合应用-1 反射的高级应用 DAO开发中,实体类对应DAO的实现类中有很多方法的代码具有高度相似性,为了提供代码的复用性,降低…...
mysql dump导出导入数据
前言 mysqldump是MySQL数据库中一个非常有用的命令行工具,用于备份和还原数据库。它可以将整个数据库或者特定的表导出为一个SQL文件,以便在需要时进行恢复或迁移。 使用mysqldump可以执行以下操作: 备份数据库:可以使用mysqld…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...

