iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Golang中Gin框架的使用入门教程
  • 680
分享到

Golang中Gin框架的使用入门教程

2024-04-02 19:04:59 680人浏览 薄情痞子
摘要

目录安装与简单测试常见请求与分组请求获取参数 与 参数合法性验证获得query中参数获得multipart/urlencoded fORM中的参数模型绑定和参数验证自定义参数验证项目

官方地址:gin-Gonic.com/docs/

安装与简单测试

下载并安装Gin包,并导入引用

$ go get -u GitHub.com/gin-gonic/gin

//将gin引入到代码中
import "github.com/gin-gonic/gin"
//可选。如果使用诸如 http.StatusOK 之类的常量,则需要引入 net/http 包
import "net/http"

编写如下测试代码

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() // 监听并在 0.0.0.0:8080 上启动服务
}

然后在浏览器中进行测试: http://localhost:8080 就可以访问到响应的请求。

常见请求与分组请求

下面展示几种其他 常规 请求方式

// 下面列出常用几种请求方式
r.GET("/someGet", handle)
r.POST("/somePost", handle)
r.PUT("/somePut", handle)
r.DELETE("/someDelete", handle)
r.PATCH("/somePatch", handle)
r.HEAD("/someHead", handle)
r.OPTioNS("/someOptions", handle)
r.Any("/any", handle)

**还可以对请求进行分组操作。 **

v1 := r.Group("/v1")
{
   v1.GET("/login", handle)
}
v2 := r.Group("/v2")
{
   v2.GET("/login", handle)
}

下面例子 是** 获得请求中path**

func main() {
   router := gin.Default()

   // 匹配/user/john
   router.GET("/user/:name", func(c *gin.Context) {
      name := c.Param("name")
      c.String(http.StatusOK, "Hello %s", name)
   })

   // 匹配/user/john/和/user/john/send
   router.GET("/user/:name/*action", func(c *gin.Context) {
      name := c.Param("name")
      action := c.Param("action")
      message := name + " is " + action
      c.String(http.StatusOK, message)
   })

   router.Run(":8080")
}

/user/:name/*action : 表示对后边路由全部模糊匹配。例如:/user/john/send/1 形式 action会匹配得到 name 是 john, action是 /send/1

获取参数 与 参数合法性验证

获得query中参数

func main() {
   router := gin.Default()

   // welcome?firstname=Jane&lastname=Doe
   router.GET("/user", func(c *gin.Context) {
      firstname := c.DefaultQuery("name", "kim") // 获取query中的name,没有的话就为kim
      lastname := c.Query("age")                 // 获取query中的age
      c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
   })
   router.Run(":8080")
}

获得multipart/urlencoded form中的参数

func main() {
   router := gin.Default()
   router.POST("/form_post", func(c *gin.Context) {
      message := c.PostForm("age")
      nick := c.DefaultPostForm("name", "kim")

      c.JSON(200, gin.H{
         "status":  "posted",
         "message": message,
         "nick":    nick,
      })
   })
   router.Run(":8080")
}

curl http://127.0.0.1:8080/form\_post -X POST -d 'name=john&age=25'

通过此curl发送post请求,即可获得表单中数据。

模型绑定和参数验证

基本用法

我们已经见识了x-www-form-urlencoded类型的参数处理,现在越来越多的应用习惯使用JSON来通信,也就是无论返回的response还是提交的request,其content-type类型都是application/json的格式。而对于一些旧的WEB表单页还是x-www-form-urlencoded的形式,这就需要我们的服务器能支持住这多种content-type的参数了。

由于go是静态语言,需要先实现定义数据模型,这就需要用到gin的model bind功能了。

gin使用go-playground/validator.v8验证参数,查看完整文档。

需要在绑定的字段上设置tag,比如,绑定格式为json,需要这样设置json:"fieldname" 。

此外,Gin还提供了两套绑定方法:

1.Must bind

  • Methods - Bind, BindJSON, BindXML, BindQuery, BindYAML
  • Behavior - 这些方法底层使用 MustBindWith,如果存在绑定错误,请求将被以下指令中止 .

c.AbortWithError(400, err).SetType(ErrorTypeBind),

响应状态代码会被设置为400,请求头Content-Type被设置为text/plain; charset=utf-8。

注意,如果你试图在此之后设置响应代码,将会发出一个警告 [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422,如果你希望更好地控制行为,请使用ShouldBind相关的方法

2.Should bind

  • Methods - ShouldBind, ShouldBindJSON, ShouldBindXML, ShouldBindQuery, ShouldBindYAML
  • Behavior - 这些方法底层使用 ShouldBindWith,如果存在绑定错误,则返回错误,开发人员可以正确处理请求和错误。

当我们使用绑定方法时,Gin会根据Content-Type推断出使用哪种绑定器,如果你确定你绑定的是什么,你可以使用MustBindWith或者BindingWith。

你还可以给字段指定特定规则的修饰符,如果一个字段用binding:"required"修饰,并且在绑定时该字段的值为空,那么将返回一个错误。

type Person struct {
   Name string `json:"name" binding:"required"`      // json格式从name取值,并且该值为必须的
   Age  int    `json:"age" binding:"required,gt=20"` // json格式从age取值,并且该值为必须的,且必须大于20
}

func main() {
   router := gin.Default()
   router.POST("/test", func(context *gin.Context) {
      var person Person
      // 这里我确定传过来的一定是JSON所以用ShouldBindJSON,否则可以用ShouldBind
      if err := context.ShouldBindJSON(&person); err != nil {
         context.JSON(http.StatusBadRequest, gin.H{
            "error": err.Error(),
         })
         return
      }
      context.JSON(http.StatusOK, gin.H{
         "success": true,
      })
   })
   router.Run(":8080")
}
curl http://localhost:8080/test -X POST -d '{"name":"Rock","age": 25}'

上面是通过json映射方式 绑定 请求数据,并且对请求数据进行验证。

自定义参数验证

验证包 gopkg.in/go-playground/validator.v8使用方法

package main

import (
   "net/http"
   "reflect"
   "time"

   "github.com/gin-gonic/gin"
   "github.com/gin-gonic/gin/binding"
   "gopkg.in/go-playground/validator.v8"
)

type Booking struct {
   // 这里的验证方法为bookabledate
   CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
   // gtfield=CheckIn表示大于的字段为CheckIn
   CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"`
}

func bookableDate(
   v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
   field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
) bool {
   // 这里有两个知识点,映射和断言
   // 在这里,field是一个reflect.Type的接口类型变量,通过Interface方法获得field接口类型变量的真实类型,可以理解为reflect.Value的逆操作
   // 在这里,断言就是将一个接口类型的变量转化为time.Time,前提是后者必须实现了前者的接口
   // 综上,这里就是将field进行了类型转换
   if date, ok := field.Interface().(time.Time); ok {
      today := time.Now()
      if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
         return false
      }
   }
   return true
}

func main() {
   route := gin.Default()

   // 注册自定义验证器
   if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
      v.ReGISterValidation("bookabledate", bookableDate)
   }

   route.GET("/bookable", getBookable)
   route.Run(":8080")
}

func getBookable(c *gin.Context) {
   var b Booking
   if err := c.ShouldBindWith(&b, binding.Query); err == nil {
      c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
   } else {
      c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
   }
}

上面方法自定义了一种参数验证器。

项目结构参考

├── conf #项目配置文件目录 │ └── config.toml #大家可以选择自己熟悉的配置文件管理工具包例如:toml、xml等等 ├── controllers #控制器目录,按模块存放控制器(或者叫控制器函数),必要的时候可以继续划分子目录。 │ ├── food.go │ └── user.go ├── main.go #项目入口,这里负责Gin框架的初始化,注册路由信息,关联控制器函数等。 ├── models #模型目录,负责项目的数据存储部分,例如各个模块的Mysql表的读写模型。 │ ├── food.go │ └── user.go ├── static #静态资源目录,包括Js,CSS,jpg等等,可以通过Gin框架配置,直接让用户访问。 │ ├── css │ ├── images │ └── js ├── logs #日志文件目录,主要保存项目运行过程中产生的日志。 └── views #视图模板目录,存放各个模块的视图模板,当然有些项目只有api,是不需要视图部分,可以忽略这个目录 └── index.html

Gin框架运行模式

为方便调试,Gin 框架在运行的时候默认是debug模式,在控制台默认会打印出很多调试日志,上线的时候我们需要关闭debug模式,改为release模式。

设置Gin框架运行模式:

通过环境变量设置 export GIN_MODE=release

GIN_MODE环境变量,可以设置为debug或者release

通过代码设置

在main函数,初始化gin框架的时候执行下面代码
// 设置 release模式
gin.SetMode(gin.ReleaseMode)
// 或者 设置debug模式
gin.SetMode(gin.DebugMode)

Gin如何获取客户ip

route.GET("/ip", func(c *gin.Context) {
   // 获取用户IP
   ip := c.ClientIP()
   c.JSON(http.StatusBadRequest, gin.H{"ip": ip})
})

Gin处理请求结果

以String类型响应请求

func (c *Context) String(code int, format string, values ...interface{})
c.String(200,"欢迎访问%s, 你是%s", "tizi360.com!","最靓的仔!")

以Json格式响应请求

我们开发api接口的时候常用的格式就是json,下面是返回json格式数据的例子

// User 定义
type User struct {
  Name  string `json:"name"` // 通过json标签定义struct字段转换成json字段的名字。
  Email string `json:"email"`
}

// Handler 控制器
func(c *gin.Context) {
  //初始化user对象
  u := &User{
    Name:  "tizi365",
    Email: "tizi@tizi365.com",
  }
  //返回json数据
  //返回结果:{"name":"tizi365", "email":"tizi@tizi365.com"}
  c.JSON(200, u)
}

以文件形式响应请求

  c.FileAttachment("/var/www/1.jpg", "1.jpg")

设置http响应头

func(c *gin.Context) {
  //设置http响应 header, key/value方式,支持设置多个header
  c.Header("site","tizi365")
}

Gin处理html模板

func main() {
    // 初始化gin对象
    router := gin.Default()
    // 首先加载templates目录下面的所有模版文件,模版文件扩展名随意
    router.LoadHTMLGlob("templates/*")
    // 绑定一个url路由 /index
    router.GET("/index", func(c *gin.Context) {
            // 通过HTML函数返回html代码
            // 第二个参数是模版文件名字
            // 第三个参数是map类型,代表模版参数
            // gin.H 是map[string]interface{}类型的别名
            c.HTML(http.StatusOK, "index.html", gin.H{
                    "title": "Main website",
            })
    })
    // 启动http服务,并且绑定在8080端口
    router.Run(":8080")
}

Gin访问静态资源文件

func main() {
    router := gin.Default()
    // 设置静态资源文件目录,并且绑定一个Url前缀
    // 静态资源文件目录:/var/www/tizi365/assets
    // /assets是访问静态资源的url前缀
    // 例如:
    //   /assets/images/1.jpg 这个url文件,存储在/var/www/tizi365/assets/images/1.jpg
    router.Static("/assets", "/var/www/tizi365/assets")

    // 为单个静态资源文件,绑定url
    // 这里的意思就是将/favicon.ico这个url,绑定到./resources/favicon.ico这个文件
    router.StaticFile("/favicon.ico", "./resources/favicon.ico")

    // Listen and serve on 0.0.0.0:8080
    router.Run(":8080")
}

Gin处理Cookie操作

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
)

func main() {
   router := gin.Default()
   // 设置cookie路由
   router.GET("/setCookie", func(c *gin.Context) {
      // 设置cookie
      c.SetCookie("site_cookie", "cookievalue", 3600, "/", "localhost", false, true)
   })
   // 获得cookie路由
   router.GET("/cookie", func(c *gin.Context) {
      data, err := c.Cookie("/cookie")
      fmt.Printf(data)
      if err != nil {
         // 直接返回cookie值
         c.String(200, data)
         return
      }
      c.String(200, "not found!")
   })
   //删除cookie路由
   router.GET("/removeCookie", func(c *gin.Context) {
      c.SetCookie("set_cookie", "cookievalue", -1, "/", "localhost", false, true)
      c.String(200, "删除cookie")
   })
   router.Run(":8080")
}

Gin文件上传

package main

// 导入gin包
import (
   "fmt"
   "github.com/gin-gonic/gin"
   "log"
   "net/http"
)

func main() {
   router := gin.Default()
   // 设置文件上传大小限制,默认是32m
   router.MaxMultipartMemory = 64 << 20 // 64 MiB

   router.POST("/upload", func(c *gin.Context) {
      // 获取上传文件,返回的是multipart.FileHeader对象,代表一个文件,里面包含了文件名之类的详细信息
      // file是表单字段名字
      file, _ := c.FormFile("file")
      // 打印上传的文件名
      log.Println(file.Filename)

      // 将上传的文件,保存到./data/1111.jpg 文件中
      c.SaveUploadedFile(file, "./data/1111.jpg")

      c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
   })
   router.Run(":8080")
}

Gin中间件

在Gin框架中,中间件(Middleware)指的是可以拦截http请求-响应生命周期的特殊函数,在请求-响应生命周期中可以注册多个中间件,每个中间件执行不同的功能,一个中间执行完再轮到下一个中间件执行。

中间件的常见应用场景如下:

  • 请求限速
  • api接口签名处理
  • 权限校验
  • 统一错误处理

Gin支持设置全局中间件和针对路由分组设置中间件,设置全局中间件意思就是会拦截所有请求,针对分组路由设置中间件,意思就是仅对这个分组下的路由起作用。

 package main

// 导入gin包
import (
   "fmt"
   "github.com/gin-gonic/gin"
   "log"
   "time"
)

// 自定义个日志中间件
func Logger() gin.HandlerFunc {
   return func(c *gin.Context) {
      t := time.Now()

      // 可以通过上下文对象,设置一些依附在上下文对象里面的键/值数据
      c.Set("example", "12345")
      fmt.Printf("1. 执行中间件设置 \n")
      // 在这里处理请求到达控制器函数之前的逻辑

      // 调用下一个中间件,或者控制器处理函数,具体得看注册了多少个中间件。
      c.Next()
      fmt.Printf("4. 完成 执行中间件设置 \n")
      // 在这里可以处理请求返回给用户之前的逻辑
      latency := time.Since(t)
      log.Print(latency)

      // 例如,查询请求状态吗
      status := c.Writer.Status()
      log.Println(status)
   }
}

func main() {
   r := gin.New()
   // 注册上面自定义的日志中间件
   r.Use(Logger())

   r.GET("/test", func(c *gin.Context) {
      // 查询我们之前在日志中间件,注入的键值数据
      fmt.Printf("2. 开始执行业务逻辑 \n")
      example := c.MustGet("example").(string)

      // it would print: "12345"
      log.Println(example)
      fmt.Printf("3. 业务逻辑执行完成 \n")
   })

   // Listen and serve on 0.0.0.0:8080
   r.Run(":8080")
}

其输出结果如下:

1. 执行中间件设置 
2. 开始执行业务逻辑 
2022/10/22 16:33:29 12345
3. 业务逻辑执行完成 
4. 完成 执行中间件设置 
2022/10/22 16:33:29 658.681µs
2022/10/22 16:33:29 200

Gin 中间件类似 node中的洋葱模型。

以上就是golang中Gin框架的使用入门教程的详细内容,更多关于Golang Gin框架的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: Golang中Gin框架的使用入门教程

本文链接: https://www.lsjlt.com/news/121314.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Golang中Gin框架的使用入门教程
    目录安装与简单测试常见请求与分组请求获取参数 与 参数合法性验证获得query中参数获得multipart/urlencoded form中的参数模型绑定和参数验证自定义参数验证项目...
    99+
    2024-04-02
  • golang中gin框架接入jwt使用token验证身份
    目录jwt 流程: 1.token 工具类 2. 使用该中间件 3. controller部分代码 jwt jwt的原理和session有点相像,其目的是为了解决rest api中...
    99+
    2024-04-02
  • .NET Core使用APB vNext框架入门教程
    目录快速入门案例.NET Core 控制台应用1. 安装 ABP 框架核心依赖2. 新建 ABP 应用的启动模块3. 新建服务,并注册到启动模块中4. 根据启动模块创建 ABP应用,...
    99+
    2024-04-02
  • golang中gin框架接入jwt如何使用token验证身份
    本篇内容介绍了“golang中gin框架接入jwt如何使用token验证身份”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!jwtjwt的原理...
    99+
    2023-06-22
  • Python中Scrapy框架的入门教程分享
    目录前言安装Scrapy创建一个Scrapy项目创建一个爬虫运行爬虫结论前言 Scrapy是一个基于Python的Web爬虫框架,可以快速方便地从互联网上获取数据并进行处理。它的设计...
    99+
    2023-03-10
    Python Scrapy框架教程 Python Scrapy框架 Python Scrapy
  • Laravel框架教程 入门篇(一)
    安装Laravel 通过Composer安装 composer create-project laravel/laravel example-appcd example-appphp artisan ...
    99+
    2023-09-01
    laravel php
  • python中的flask框架Jinja 模板入门教程
    目录1、快速体验2、Flask 最小 DEMO3、模板继承4、Super Blocks5、Macros6、自定义过滤器7、结论Flask 和 Django 附带了强大的 Jinja ...
    99+
    2024-04-02
  • Gin框架中bind怎么使用
    本篇内容主要讲解“Gin框架中bind怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Gin框架中bind怎么使用”吧!概述Gin框架中,有bind函数可以非常方便的将url的查询参数qu...
    99+
    2023-06-22
  • 浅谈Gin框架中bind的使用
    目录概述Binding接口context.Bindcnotext.MustBindWithShouldBindWithcontext.BindJSONcontext.ShouldBi...
    99+
    2024-04-02
  • C#使用Thrift作为RPC框架入门详细教程
    前言 本文将介绍由 Facebook 开发的远程服务调用框架 Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种...
    99+
    2024-04-02
  • Gin-高性能 Golang Web框架的介绍和使用
    偶遇 Gin 我之前一直在使用 Beego 框架来做应用的 Api,因为它的写法跟 PHP 的 MVC 一样,上手简单,所以对它的表现还算满意。用的久了,发现 Beego 的编程思想就是照搬了 PHP 的那一套,写法上倒没什么,但是在...
    99+
    2024-04-02
  • gin框架中怎么使用JWT
    这篇文章主要讲解了“gin框架中怎么使用JWT”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“gin框架中怎么使用JWT”吧!什么是JWT?JWT全称JSON Web Token是一种跨域认证...
    99+
    2023-06-30
  • JavaScript与JQuery框架基础入门教程
    目录一,JS对象二,DOM–1,作用–2,测试三,Jquery–1,概述–2,使用步骤–3,入门案例–4,jQuery的文档就绪四,JQuery的语法–1,选择器–2,常用函数–3,...
    99+
    2024-04-02
  • Golang使用Gin框架实现HTTP上传文件过程介绍
    目录HTTP上传的文件的原理Gin框架文件上传Demo限制文件上传的大小文件类型验证文件上传进度-后台计算文件上传进度HTTP上传的文件的原理 HTTP协议的文件上传是通过HTTP ...
    99+
    2023-05-15
    Go HTTP上传文件 Go Gin框架上传文件
  • Golang怎么使用Gin框架实现HTTP上传文件
    本文小编为大家详细介绍“Golang怎么使用Gin框架实现HTTP上传文件”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang怎么使用Gin框架实现HTTP上传文件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知...
    99+
    2023-07-05
  • Brute Ratel C4红队框架 brc4 1.2.2入门使用教程(注册机使用)
    目录 1、前言 2、准备阶段 3、注册机安装 4、登录教程 5、使用教程 1.Operator​编辑 2.C4 Profiler  1.Add Http Listener 2.Add DOH Listener 3.Hosted Files ...
    99+
    2023-09-07
    python 网络安全 qt
  • AndroidButterKnife依赖注入框架使用教程
    目录ButterKnife的工作原理BuffterKnife 采用 注解+ APT技术 APT:Annotation Processor tool 注解处理器,是javac的一个工具...
    99+
    2023-02-23
    Android ButterKnife依赖注入 Android ButterKnife Android依赖注入
  • Java持久层框架Mybatis入门详细教程
    mybatis介绍 mybatis它是轻量级持久层框架,由ibatis演化而来。它自动连接数据库,将数据库的结果集封装到对象中POJO。 POJO: 一个简单的Java类,这个类没...
    99+
    2024-04-02
  • Shell 技能在 PHP 框架教程中的应用:从入门到精通。
    Shell 技能在 PHP 框架教程中的应用:从入门到精通 Shell 是 Linux 操作系统中的一种命令行解释器,它提供了许多方便快捷的命令来帮助我们管理系统。在 PHP 框架开发中,Shell 技能也扮演了重要角色。本篇文章将介绍 S...
    99+
    2023-08-18
    框架 教程 shell
  • python playwrigh框架入门安装使用
    目录前言优势举个栗子安装入门篇安装前言 这是一篇罗里吧嗦的前言,可能更多的属于个人的感慨以及吐槽。 首先打个广告:你每天点点点累么?面对越来越卷的环境你彷徨么?被要求 2 天做一个系...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作