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…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

