github地址: https://github.com/gin-gonic/gin

初体验

安装: $ go get -u github.com/gin-gonic/gin

简单实例:

package main

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

func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
_ = r.Run()
}

启动一个HTTP服务进程,默认监听在8080端口

gin.Default实例化一个GIN对象

该对象的GET方法,参数表中分别是路径和多个handler

// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}

handlerFunc的具体类型:

// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)

按照这种格式定义函数:

func pong(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
} func main() {
r := gin.Default()
r.GET("/ping", pong)
_ = r.Run(":9090")
}

同时在Run中可以指定端口号,不使用默认端口号

gin.H是一个map:

// H is a shortcut for map[string]interface{}
type H map[string]any

所以如下方法同理:

func pong(c *gin.Context) {
var m = map[string]string{
"message": "pong",
}
c.JSON(http.StatusOK, m)
}

初始化路由

除了上述的gin.Default方法,还可以使用gin.New来创建路由,前者会开启两个中间件,分别是Logger和Recovery:

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}

Logger负责日志,Recovery负责异常处理

只使用New方法便不会开启这两个功能

配置路由:

func getting(c *gin.Context) {
c.JSON(http.StatusOK,gin.H{
"message":"getting",
})
} func posting(c *gin.Context) {
c.JSON(http.StatusOK,gin.H{
"message":"posting",
})
} func main() {
router := gin.Default()
router.GET("/get", getting)
router.GET("/post", posting)
_ = router.Run()
}

路由分组

使用Group方法进行路由分组

func main() {
router := gin.Default() router.GET("/goods/list",goodsList)
router.POST("/goods/add",createGoods) _ = router.Run()
}

使用路由分组改写,与上方同理:

func main() {
router := gin.Default() goodsGroup := router.Group("/goods")
goodsGroup.GET("/list", goodsList)
goodsGroup.GET("/add", createGoods) _ = router.Run()
}

获取参数

带参数URL:

func main() {
router := gin.Default() goodsGroup := router.Group("/goods")
goodsGroup.GET("/", goodsList)
goodsGroup.POST("", createGoods)
goodsGroup.GET("/:id", goodsDetail) _ = router.Run()
} func createGoods(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{})
} func goodsDetail(c *gin.Context) {
id := c.Param("id")
c.JSON(http.StatusOK, gin.H{
"id": id,
})
} func goodsList(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "list",
})
}

这里id会作为参数,例如访问http://localhost:8080/1,id便等于1

如下可扩展为多参数:

func goodsDetail(c *gin.Context) {
id := c.Param("id")
action := c.Param("action")
c.JSON(http.StatusOK, gin.H{
"id": id,
"action": action,
})
}

访问http://localhost:8080/goods/1/detail,便会携带两个参数

获取GET/POST传参:

func main() {
router := gin.Default()
router.GET("/welcome", welcome)
router.POST("/login", login)
router.POST("/post", getPost)
_ = router.Run()
} // 获取GET传参
func welcome(c *gin.Context) {
firstName := c.DefaultQuery("firstname", "unknown")
lastName := c.DefaultQuery("lastname", "unknown")
c.JSON(http.StatusOK, gin.H{
"first_name": firstName,
"last_name": lastName,
})
} // 获取POST传参
func login(c *gin.Context) {
username := c.DefaultPostForm("username", "test")
password := c.DefaultPostForm("password", "test")
c.JSON(http.StatusOK, gin.H{
"username": username,
"password": password,
})
} // 混合获取参数
func getPost(c *gin.Context) {
// 获取GET参数
id := c.Query("id")
page := c.DefaultQuery("page", "0")
// 获取POST参数
name := c.PostForm("name")
message := c.DefaultPostForm("message", "")
c.JSON(http.StatusOK, gin.H{
"id": id,
"page": page,
"name": name,
"message": message,
})
}

使用如下python代码进行测试:

import requests

url = "http://127.0.0.1:8080/post"
data = {
"name": "David",
"message": "test",
} params = {
"id": 1,
"page": 2
} resp = requests.post(url,params=params,data=data)
print(resp.text)

JSON渲染

将结构体序列化为JSON字符串

func main() {
router := gin.Default()
router.GET("/moreJSON", moreJSON)
_ = router.Run()
} func moreJSON(c *gin.Context) {
var message struct {
Name string `json:"name"`
Message string
Number int
}
message.Name = "David"
message.Message = "json test"
message.Number = 20 c.JSON(http.StatusOK, message)
}

表单验证

GIN提供了两种方法来进行表单验证: Must Bind / Should Bind,其中要搭配validate

接收表单请求,获取用户名和密码:

type LoginForm struct {
User string `json:"user" binding:"required,min=3,max=20"`
Password string `json:"password" binding:"required"`
} type SignUpForm struct {
Age uint8 `json:"age" binding:"gte=1,lte=130"`
Name string `json:"name" binding:"required,min=3"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required"`
RePassword string `json:"repassword" binding:"required,eqfield=Password"`
} func main() {
router := gin.Default()
router.POST("/loginJSON", func(c *gin.Context) {
var loginForm LoginForm
if err := c.ShouldBind(&loginForm); err != nil {
fmt.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
c.JSON(http.StatusOK, gin.H{
"msg": "login",
})
}) router.POST("/signup", func(c *gin.Context) {
var signupForm SignUpForm
if err := c.ShouldBind(&signupForm); err != nil {
fmt.Println(err.Error())
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
})
_ = router.Run()
}

使用POST请求发送JSON数据

登录:

{
"user":"David",
"password":"123"
}

注册:

{
"name":"David",
"age":12,
"email" :"1@qq.com",
"password":"123",
"re_password":"123"
}

自定义中间件

上文有提到,gin.Default使用了两个中间件:

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}

用户可以自己定义中间件

满足如下形式即可:

// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)

如下所示,用于检查token:

func TokenRequired() gin.HandlerFunc {
return func(c *gin.Context) {
var token string
for k, v := range c.Request.Header {
if k == "x-token" {
token = v[0]
}
fmt.Println(k, v, token)
}
if token != "test" {
c.JSON(http.StatusOK, gin.H{
"msg": "login failed",
})
c.Abort()
}
c.Next()
}
} func main() {
router := gin.Default()
router.Use(TokenRequired())
router.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
_ = router.Run()
}

Gin框架快速入门的更多相关文章

  1. flask 框架快速入门

    flask 框架快速入门 搭建一个简易flask项目 首先使用 Pycharm创建flask项目 运行flask项目 1.使用Pycharm搭建flask项目 (如果Pycharm新建项目中未出现该图 ...

  2. struts2框架快速入门小案例

    struts2快速入门: index.jsp------>HelloAction--------->hello.jsp struts2流程 1.导入jar包 struts2的目录结构: a ...

  3. Scrapy框架-scrapy框架快速入门

    1.安装和文档 安装:通过pip install scrapy即可安装. Scrapy官方文档:http://doc.scrapy.org/en/latest Scrapy中文文档:http://sc ...

  4. IDEA工具下Mybaties框架快速入门程序

    本篇文章介绍在IDEA工具下mybatis快速入门程序分为以下五步 ​ 1 添加依赖包 ​ 2 编写pojo对象 ​ 3 编写映射文件 ​ 4 编写核心配置文件 ​ 5 测试框架 详细如下 建立Mod ...

  5. vue-element-admin框架快速入门

    年底了,最近公司也不是太忙,感觉今年互联网行业都遇到寒冬,不在是前两年像热的发烫的赛道.这几天完成公司项目系统的优化和升级,目前准备想开发一套前后端分离的系统.       现在java最新最火的技术 ...

  6. 01 . Go框架之Gin框架从入门到熟悉(路由和上传文件)

    Gin框架简介 Gin是使用Go/Golang语言实现的HTTP Web框架, 接口简洁, 性能极高,截止1.4.0版本,包含测试代码,仅14K, 其中测试代码9K, 也就是说测试源码仅5k左右, 具 ...

  7. Go最火的Gin框架简单入门

    Gin 介绍 Gin 是一个 Golang 写的 web 框架,具有高性能的优点,,基于 httprouter,它提供了类似martini但更好性能(路由性能约快40倍)的API服务.官方地址:htt ...

  8. mybatis框架快速入门

    通过快速入门示例,我们发现使用mybatis 是非常容易的一件事情,因为只需要编写 Dao 接口并且按照 mybatis要求编写两个配置文件,就可以实现功能.远比我们之前的jdbc方便多了.(我们使用 ...

  9. java框架--快速入门

    spring快速入门    1.创建项目        1.1创建项目文件夹        1.2启动idea ->文件->打开->点击创建的项目文件夹        1.3右键创建 ...

  10. 【Go语言系列】第三方框架和库——GIN:快速入门

    要求要安装Gin软件包,需要:1.安装Go(需要1.11+版本)2.设置Go工作区 安装1.下载并安装 gin: $ go get -u github.com/gin-gonic/gin 2.将 gi ...

随机推荐

  1. 基于CMMI的软件工程及实训指导 第一章

    第一章 软件工程基础 1. 软件工程概述 1.1 软件工程概念 软件工程是从管理和技术两方面来研究如何采用工程的概念.原理和技术方面并加以综合,指导开发人员更好地开发和维护计算机软件的一门新学科. 1 ...

  2. 实验七:基于REST API的SDN北向应用实践

    (一)基本要求 编写Python程序,调用OpenDaylight的北向接口实现以下功能 (1) 利用Mininet平台搭建下图所示网络拓扑,并连接OpenDaylight: (2) 下发指令删除s1 ...

  3. python调用adb shell

    最近在用python做一个小工具,自动执行一些adb shell命令,使用subprocess.Popen来实现. 不过遇到个问题就是执行adb shell后就无法执行后面adb shell里的命令了 ...

  4. 【打怪升级】【rocketMq】rocket的持久化

    rocket持久化保证的思想有两点:1是刷盘保证大部分数据不丢失:2是持久化文件的处理,零拷贝技术和内存页,NIO模型保证处理能力 文件持久化目录 ├──abort:rocket broker启动检查 ...

  5. SpringBoot使用OkHttp

    参考文章: https://www.cnblogs.com/hongdada/p/9259965.html https://blog.csdn.net/qq_41890954/article/deta ...

  6. Linux系统下祼机安装mysql8.0和docker mysql 8.0 性能差异对比~

    环境准备 准备两台服务器环境,配置相同,分别安装Centos7,mysql8.0,docker mysql 8.0 准备测试代码 public class Chat { public static l ...

  7. Go内存管理逃逸分析

    1. 前言 所谓的逃逸分析(Escape analysis)是指由编译器决定内存分配的位置吗不需要程序员指定. 函数中申请一个新的对象 如果分配在栈中, 则函数执行结束后可自动将内存回收 如果分配在堆 ...

  8. vue项目如何解决跨域问题

    跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能 所谓同源(即指在同一个域)具有以下三个相同点 ​ ...

  9. CentOS 7下安装windows字体

    1.在日常生产中打开文件时发现中文乱码,考虑到编码或者是否有中文字体库,在CentOS 7中执行命令发现字体列表命令无效. 上图发现字体库都没安装,接下来就会简单说一下CentOS 7 中安装字体库和 ...

  10. 如何使用Photino创建Blazor项目进行跨平台

    Photino是什么 Photino是一组使用Web (HTML/CSS/JavaScript)UI创建桌面应用程序的技术.TryPhotino.io 维护 .NET 构建,并鼓励社区开发 Photi ...