为了账号安全,请及时绑定邮箱和手机立即绑定

Gin入门实战

难度入门
时长 2小时15分
学习人数
综合评分7.80
28人评价 查看评价
7.6 内容实用
8.0 简洁易懂
7.8 逻辑清晰
  • package main
    
    import (
       "github.com/gin-gonic/gin"
       "gopkg.in/go-playground/validator.v9"
       "net/http"
       "time"
    )
    
    type Booking struct {
       CheckIn time.Time `form:"check_in" validate:"required,bookableDate" time_format:"2006-01-02"`
       CheckOut time.Time `form:"check_out" validate:"required,gtfield=CheckIn" time_format:"2006-01-02"`
    }
    
    
    func main(){
    
       r := gin.Default()
    
       validate := validator.New()
       validate.RegisterValidation("bookableDate", bookableDate)
       r.GET("/bookable", func(c *gin.Context) {
          var book Booking
          if err := c.ShouldBind(&book); err != nil {
             c.JSON(http.StatusInternalServerError, gin.H{
                "error": err.Error(),
             })
             c.Abort()
             return
          }
          if err := validate.Struct(book); err != nil {
             c.JSON(http.StatusInternalServerError, gin.H{
                "error": err.Error(),
             })
             c.Abort()
             return
          }
    
          c.JSON(http.StatusOK, gin.H{
             "message": "OK",
             "booking": book,
          })
       })
    
       r.Run()
    }
    
    func bookableDate(fl validator.FieldLevel) bool {
    
       if date, ok := fl.Field().Interface().(time.Time); ok {
          today := time.Now()
          if date.Unix() > today.Unix() {
             return true
          }
       }
    
       return false
    }


    查看全部
  • package main
    
    import (
       "github.com/gin-gonic/gin"
       "github.com/go-playground/locales/en"
       "github.com/go-playground/locales/zh"
       "github.com/go-playground/universal-translator"
       "gopkg.in/go-playground/validator.v9"
       en2 "gopkg.in/go-playground/validator.v9/translations/en"
       zh2 "gopkg.in/go-playground/validator.v9/translations/zh"
       "net/http"
       "time"
    )
    
    type Booking struct {
       CheckIn time.Time `form:"check_in" validate:"required,bookableDate" time_format:"2006-01-02"`
       CheckOut time.Time `form:"check_out" validate:"required,gtfield=CheckIn" time_format:"2006-01-02"`
    }
    
    
    func main(){
    
       r := gin.Default()
    
       zhTranslate := zh.New()
       enTranslate := en.New()
       Uni := ut.New(zhTranslate, enTranslate)
    
       validate := validator.New()
       _ = validate.RegisterValidation("bookableDate", bookableDate)
    
       r.GET("/bookable", func(c *gin.Context) {
          locale := c.DefaultQuery("locale", "zh")
          trans, _ := Uni.GetTranslator(locale)
          switch locale {
          case "zh":
             _ = validate.RegisterTranslation("bookableDate", trans, registerBookableDateTranslation, bookableDateTranslation)
             _ = zh2.RegisterDefaultTranslations(validate, trans)
             break
          case "en":
             _ = en2.RegisterDefaultTranslations(validate, trans)
             break
          default:
             _ = validate.RegisterTranslation("bookableDate", trans, registerBookableDateTranslation, bookableDateTranslation)
             _ = zh2.RegisterDefaultTranslations(validate, trans)
          }
    
          var book Booking
          if err := c.ShouldBind(&book); err != nil {
             c.JSON(http.StatusInternalServerError, gin.H{
                "error": err.Error(),
             })
             c.Abort()
             return
          }
          if err := validate.Struct(book); err != nil {
             errs := err.(validator.ValidationErrors)
    
             var sliceErrs []string
             for _, v := range errs {
                sliceErrs = append(sliceErrs, v.Translate(trans))
             }
    
             c.JSON(http.StatusInternalServerError, gin.H{
                "error": sliceErrs,
             })
             c.Abort()
             return
          }
    
          c.JSON(http.StatusOK, gin.H{
             "message": "OK",
             "booking": book,
          })
       })
    
       _ = r.Run()
    }
    
    func bookableDate(fl validator.FieldLevel) bool {
    
       if date, ok := fl.Field().Interface().(time.Time); ok {
          today := time.Now()
          if date.Unix() > today.Unix() {
             return true
          }
       }
    
       return false
    }
    
    func registerBookableDateTranslation(ut ut.Translator) error {
       return ut.Add("bookableDate", "{0} 日期必须大于当天日期!", true)
    }
    
    func bookableDateTranslation(ut ut.Translator, fe validator.FieldError) string {
       t, _ := ut.T("bookableDate", fe.Field())
       return t
    }


    查看全部
  • 老师棒棒哒
    查看全部
    4 采集 收起 来源:课程总结

    2019-09-06

  • Gin脚手架文件结构说明:

        conf/   #配置文件目录-下一层#环境文件夹

                    /dev  #开发环境

                            base.toml*  #基本配置存储

                            mysql_map.toml*  #mysql配置存储

                            redis_map.toml*    #redis配置存储

        controller/   #控制器类-按照文件名区分不同的请求,同一请求汇聚到同一文件

        dao/    #数据访问的对象层-一般存储的是RM

        dto/    #数据传输对象层-输入的参数转化为实际的对象

        middleware/    #中间件层-日志的打印和请求的拦截,以及session和多语言的处理也可以放在这里

        public/    #公共层-放置一些公共的函数

        router/    #路由层-路由的配置请求的配置

        tmpl/        #模版文件存储位置

                                    

    查看全部
  • 传统关停服务器的方式,开始有一个gin实例,gin.run通过阻塞监听端口,请求过来之后会请求回调函数提供服务,结束之后就直接终止了

    优雅关停的方式,可以使用一个server.ListenAndServer构建一个server来代替gin.Run,它是不阻塞的

    另外使用os.Signal来阻塞进程,监听关闭信号,如果获取到信号就将超时的上下文传递到server的shutdwon方法里才正式退出

    从监听到信号到真正的结束之前,会关闭这个时间段内的连接请求,并且要在超时时间内把已经接收到请求执行完毕


    查看全部
  • 学完了,内容比较简单,脚手架那章没什么实际内容
    查看全部
    1 采集 收起 来源:课程总结

    2020-05-16

  • curl -X GET http://127.0.0.1:8080/api/hello

    查看全部
  • #出事换环境

    https://beego.gocn.vip/beego/zh/developing/bee/env.html

    #go语言安装主根目录

    export GOROOT=/usr/local/go   

    #替换你的目录#GOPATH 是自己的go项目路径,自定义设置export GOPATH=/Users/ding/go_workspace #替换你的目录#GOBIN 当我们使用go install命令编译后并且安装的二进制程序目录export GOBIN=$GOPATH/bin# 启用 Go Modules 功能export GO111MODULE=on# 配置 GOPROXY 环境变量。你可以换成你喜欢的 proxyexport GOPROXY=https://goproxy.cn,direct# 加入环境变量中export PATH=$PATH:$GOROOT/bin:$GOBIN

    # 创建文件夹

    mkdir  -p  $GOPAH/src/github.com/rupid/learn-gin

    # 进入learn-gin文件夹

    cd $_


    # 初始化mod

    go mod init

    # 拉去gin的模块

    go  get  -v github.com/gin-gonic/gin@v1.7


    查看全部
  • 待了解的前置知识:

    - go基本语法

    - go写成基本知识


    开发工具

    - goland

    查看全部
  • 老师是在liunx下教学的,windows的命令行更改如下

    mkdir -p $GOPATH/src/github.com/e421083458/gin_test_project
    换成
    mkdir -p $env:GOPATH/src/github.com/e421083458/gin_test_project
    export GO111MODULE=on
    换成
    go env -w GO111MODULE=on

    这个on不能是大写,而且只有on,off,auto
    如果设置错了值,可以看这篇文章
    windows错误设置GO111MODULE报错解决

    设置好GO111MODULE之后,可以设置代理,下载速度会快一点

    go env -w GOPROXY=https://goproxy.cn,direct
    查看全部
  • 自动申请证书

    autotls.Run(r, "域名")

    流程:

    1、生成本地密钥

    2、发送密钥到证书颁发机构 => 获取私钥

    3、私钥验证,验证后保存,下次请求用私钥加密 => 自动下载证书

    查看全部

  • 1、加载模板文件

    r.LoadHTMLGlob("template/*")

    2、处理模板数据

    c.HTML(200, "index.html", gin.H{
        "title": "test_gin_template"
    })
    查看全部
  • package mainimport (   "context"
       "github.com/gin-gonic/gin"
       "log"
       "net/http"
       "os"
       "os/signal"
       "syscall"
       "time")func main()  {
       r := gin.Default()
       r.GET("/other_shutdown", func(c *gin.Context) {
          time.Sleep(10*time.Second)
          c.String(200, "test other shutdown")
       })
    
       srv := &http.Server{
          Addr: ":8085",
          Handler: r,
       }   go func() {      if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
             log.Fatalf("listen:%s\n", err)
          }
       }()
    
       quit := make(chan os.Signal)
       signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
       <-quit
       log.Println("shutdown server...")
    
       ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)   defer cancel()   if err := srv.Shutdown(ctx); err != nil {
          log.Fatal("server shutdown:", err)
       }
    
       log.Println("server exiting")
    }


    1、时间库使用

    time.Sleep(10*time.Second) // 表示等待10秒

    2、使用http.Server 构建server

    srv := &http.Server{
      // 地址
      Addr: ":8085",
      Handler: r,
    }

    3、goroutine创建协程并使用

    go func() {   
      if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {  
      }
    }()

    4、信号 os.Signal - 请求拦截

    quit := make(chan os.Signal)
    // 捕获 ctrl+c 和 kill -15 终止两类, kill -9捕获不到
    signal.Notify(quit, syscall.S IGINT, syscall.SIGTERM)
    // 阻塞channel
    <-quit

    5、设置超时的上下文

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)

    6、defer

    7、执行关闭服务器

    srv.Shutdown(ctx)
    查看全部
  • package main
    
    import (
       "fmt"
       "github.com/gin-gonic/gin"
       "net/http"
    )
    
    func IPAuthMiddleware() gin.HandlerFunc {
       return func(c *gin.Context) {
          ipList := []string{
             "127.0.0.2",
          }
          flag := false
          clientIP := c.ClientIP()
          for _, ip := range ipList {
             if ip == clientIP {
                flag = true
                break
             }
          }
          if !flag {
             c.String(http.StatusUnauthorized, "%s not in ip list", clientIP)
             c.Abort()
          }
       }
    }
    func main()  {
    
       r := gin.Default()
       r.Use(IPAuthMiddleware())
       
       r.GET("whitelist_middleware_gin", func(c *gin.Context) {
          c.String(200, c.ClientIP())
       })
       
       err := r.Run()
       if err != nil {
          fmt.Println(err)
       }
    }

    1、ip数组初始化:

    ipList := []string{
        "127.0.0.2",
    }


    2、获取客户端ip

    c.ClientIP()


    3、自定义中间件:

    3.1 定义中间件方法
    func IPAuthMiddleware() gin.HandlerFunc {
       return func(c *gin.Context) {
         
       }
    }
    
    3.2 使用中间件
    r.Use(IPAuthMiddleware())


    4、中间件校验不通过直接退出

    c.Abort() // 不终止退出的话,会继续调用接口,输出接口内容,与中间件检验拦截目的不符
    查看全部
  • package main
    
    import (
       "bytes"
       "fmt"
       "github.com/gin-gonic/gin"
       "io/ioutil"
       "net/http"
    )
    
    func main()  {
       r := gin.Default()
       r.POST("/test", func(c *gin.Context) {
          bodyBytes, err := ioutil.ReadAll(c.Request.Body)
    
          if err != nil {
             c.String(http.StatusBadRequest, err.Error())
             c.Abort()
          }
    
          c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
          name := c.PostForm("name")
          c.String(http.StatusOK, "%s, %s", name, string(bodyBytes))
       })
    
       err := r.Run()
       if err != nil {
          fmt.Println(err)
       }
    }



    curl -X POST "http://127.0.0.1:8080/test" -d "name=zqunor"

    虽然能实现,但是感觉回传不是个好方案。

    查看全部
首页上一页12345下一页尾页

举报

0/150
提交
取消
课程须知
1、有golang基础语法即可
老师告诉你能学到什么?
1、通过gin了解到golang web开发的核心基础 2、掌握如何编写一个golang脚手架 3、开发用户管理系统基于golang脚手架 4、了解线上部署流程

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!