当前位置: 首页 > article >正文

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 Response
	ginServer.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 Response
	ginServer.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 Response
	ginServer.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,我们转成string
		usersesion := 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/xxx
	ginServer.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 就是 NoRoute
	ginServer.NoRoute(func(context *gin.Context) {
		context.HTML(http.StatusNotFound, "404.html", nil)
	})

	userGroup := ginServer.Group("/user")
	{
		//我们去网页访问的时候,就想当关于 /user/list
		userGroup.GET("/list", func(context *gin.Context) {
			context.JSON(http.StatusOK, gin.H{
				"msg": "获取用户列表",
			})
			//我们去网页访问的时候,就想当关于 /user/info
			userGroup.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!!!

创作不易,希望读者三连支持??
赠人玫瑰,手有余香??


http://www.kler.cn/a/465007.html

相关文章:

  • 【游戏设计原理】47 - 超游戏思维
  • 离散数学 期末笔记
  • GESP真题 | 2024年12月1级-编程题2《奇数和偶数》及答案(Python版)
  • 文献阅读 | B. S. Carmo 2010
  • UniApp | 从入门到精通:开启全平台开发的大门
  • xdoj ROT13加密
  • 【Triton-ONNX】如何使用 ONNX 模型服务与 Triton 通信执行推理任务上-Triton快速开始
  • 【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?
  • flutter组件————Row和Column
  • 【sql】CAST(GROUP_CONCAT())实现一对多对象json输出
  • 办公 三之 Excel 数据限定录入与格式变换
  • 机器学习-感知机-神经网络-激活函数-正反向传播-梯度消失-dropout
  • 无需训练!多提示视频生成最新SOTA!港中文腾讯等发布DiTCtrl:基于MM-DiT架构
  • Windows系统提示ffmpeg.dll丢失怎么解决?
  • 详细讲解外部导入Excel通过命令行形式导数据库中
  • Elasticsearch 在 Java 中的使用教程
  • Golang互斥锁正常模式和饥饿模式的区别
  • 信息科技伦理与道德1:绪论
  • Java的基础概念(二)
  • MySQL中distinct和group by去重的区别
  • 力扣--LCR 167.招式拆解I
  • LeetCode7. 整数反转
  • 基于物联网的冻保鲜运输智能控制系统
  • MySQL实用SQL示例
  • 利用Java爬虫获取亚马逊国际按关键字搜索商品的实践指南
  • SQL偏移类窗口函数—— LAG()、LEAD()用法详解