Go --- gin基础知识点(二)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Go --- gin基础知识点

路由组

  • 用来管理有相同的URL的路由

使用示例:

package main
import (
    "fmt"
    "github.com/gin-gonic/gin"
)
// 路由组
func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    // 路由组1 ,处理GET请求
    v1 := r.Group("/v1")
    // {} 是书写规范
    {
        v1.GET("/login", login)
        v1.GET("submit", submit)
    }
    v2 := r.Group("/v2")
    {
        v2.POST("/login", login)
        v2.POST("/submit", submit)
    }
    r.Run(":8000")
}
func login(c *gin.Context) {
    name := c.DefaultQuery("name", "jack")
    c.String(200, fmt.Sprintf("hello %s\n", name))
}
func submit(c *gin.Context) {
    name := c.DefaultQuery("name", "lily")
    c.String(200, fmt.Sprintf("hello %s\n", name))
}

访问失败页面

使用r.NoRoute来设置

例如:

r.NoRoute(func(c *gin.Context) {
        c.String(http.StatusNotFound, "sorry,天太冷了,页面跑去钻小被窝了")
})

结果:

gin路由原理

gin数据解析和绑定

Json数据解析和绑定

  • 客户端传参,Json格式,服务端解析到结构体
  • 使用gin.Context.ShouldBindJSON(&json) err将接收到的json数据解析到结构体中
User    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
  • 解析中binding中的required该字段表示必须传参,如果不传参则会报错

表单数据解析和绑定

  • 使用gin.Context.Bind(&form) err 将接收到的表单数据解析到结构体中
··<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单提交数据解析到结构体</title>
</head>
<body>
    <form action="http://localhost:8000/loginForm" method="post" enctype="application/x-www-form-urlencoded">
    用户名:<input type="text" name="username"><br>
    密&nbsp码:<input type="password" name="password"><br>
    <input type="submit" value="提交">
    </form>
</body>
</html>
package main
import (
    "github.com/gin-gonic/gin"
    "net/http"
)
type Login struct {
    // binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
    User    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
    Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}
func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    // JSON绑定
    r.POST("/loginForm", func(c *gin.Context) {
        // 声明接收的变量
        var form Login
        // Bind()默认解析并绑定form格式
        // 根据请求头中content-type自动推断
        if err := c.Bind(&form); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        // 判断用户名密码是否正确
        if form.User != "root" || form.Pssword != "admin" {
            c.JSON(http.StatusBadRequest, gin.H{"status": http.StatusBadRequest})
            return
        }
        c.JSON(http.StatusOK, gin.H{"status": http.StatusOK,"body":form})
    })
    r.Run(":8000")
}

结果:

URI数据解析和绑定

  • 使用gin.Context.ShouldBindUri(&login) err 解析uri数据到结构体中

示例:

func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    // JSON绑定
    r.GET("/:user/:password", func(c *gin.Context) {
        // 声明接收的变量
        var login Login
        // Bind()默认解析并绑定form格式
        // 根据请求头中content-type自动推断
        if err := c.ShouldBindUri(&login); err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        // 判断用户名密码是否正确
        if login.User != "root" || login.Pssword != "admin" {
            c.JSON(http.StatusBadRequest, gin.H{"status": "304"})
            return
        }
        c.JSON(http.StatusOK, gin.H{"status": "200"})
    })
    r.Run(":8000")
}

结果:

gin 渲染

各种数据格式的响应

  • json、结构体、XML、YAML类似于java的properties、ProtoBuf
func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    // 1.json
    r.GET("/someJSON", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "someJSON", "status": http.StatusOK})
    })
    // 2. 结构体响应
    r.GET("/someStruct", func(c *gin.Context) {
        var msg struct {
            Name    string
            Message string
            Number  int
        }
        msg.Name = "root"
        msg.Message = "message"
        msg.Number = 123
        c.JSON(http.StatusOK, msg)
    })
    // 3.XML
    r.GET("/someXML", func(c *gin.Context) {
        c.XML(200, gin.H{"message": "abc"})
    })
    // 4.YAML响应
    r.GET("/someYAML", func(c *gin.Context) {
        c.YAML(200, gin.H{"name": "zhangsan"})
    })
    // 5.protobuf格式,谷歌开发的高效存储读取的工具
    // 数组?切片?如果自己构建一个传输格式,应该是什么格式?
    //r.GET("/someProtoBuf", func(c *gin.Context) {
    //    reps := []int64{int64(1), int64(2)}
    //    // 定义数据
    //    label := "label"
    //    // 传protobuf格式数据
    //    data := &protoexample.Test{
    //        Label: &label,
    //        Reps:  reps,
    //    }
    //    c.ProtoBuf(200, data)
    //})
    r.Run(":8000")
}

XML页面结果:

HTML模板渲染

  • gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数据,本质上就是字符串替换
  • LoadHTMLGlob()方法可以加载模板文件

html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.title}}</title>
</head>
<body>
    <h1>{{.test}}</h1>
</body>
</html>

go文件:

package main
import (
    "github.com/gin-gonic/gin"
    "net/http"
)
// html模板渲染
func main() {
    r := gin.Default()
    // 加载模板文件
    r.LoadHTMLGlob("static/*")
    // 如果项目结构不同,也可以是
    // r.LoadHTMLGlob("static/**/*")
    r.GET("/index", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.html", gin.H{"title": "我是测试", "test": "这是一个测试文件"})
    })
    r.Run(":8000")
}

结果:

重定向

  • 使用 gin.Context.Redirect 进行重定向
package main
import (
    "github.com/gin-gonic/gin"
    "net/http"
)
// 重定向
func main() {
    r := gin.Default()
    r.GET("/index", func(c *gin.Context) {
        c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
    })
    r.Run(":8000")
}

同步异步

  • 同步:先执行再响应
  • 异步:先响应再执行
  • go的协程机制(goroutine)可以方便地实现异步处理
  • 另外,在启动新的goroutine时,不应该使用原始上下文,必须使用它的只读副本
package main
import (
    "github.com/gin-gonic/gin"
    "log"
    "time"
)
// 同步异步
func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    // 1.异步
    r.GET("/long_async", func(c *gin.Context) {
        // 需要搞一个副本
        copyContext := c.Copy()
        // 异步处理
        go func() {
            time.Sleep(30 * time.Second)
            log.Println("异步执行:" + copyContext.Request.URL.Path)
        }()
    })
    // 2.同步
    r.GET("/long_sync", func(c *gin.Context) {
        time.Sleep(30 * time.Second)
        log.Println("同步执行:" + c.Request.URL.Path)
    })
    r.Run(":8000")
}

结果:

相关文章
|
6月前
|
中间件 Go 数据库
Go开发者必读:Gin框架的实战技巧与最佳实践
在当今快速发展的互联网时代,Web开发的需求日益增长。Go语言以其简洁、高效、并发性强的特点,成为了开发者们的首选。而在Go语言的众多Web框架中,Gin无疑是其中的佼佼者。本文将深入探讨Gin框架的特性、优势以及如何利用Gin构建高性能的Web应用。
|
5月前
|
Go 数据安全/隐私保护
go 基于gin编写encode、decode、base64加密接口
go 基于gin编写encode、decode、base64加密接口
48 2
|
2月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
4月前
|
JSON 中间件 Go
Go语言Web框架Gin介绍
【7月更文挑战第19天】Gin是一个功能强大、高性能且易于使用的Go语言Web框架。它提供了路由、中间件、参数绑定等丰富的功能,帮助开发者快速构建高质量的Web应用。通过本文的介绍,你应该对Gin框架有了初步的了解,并能够使用它来开发简单的Web服务。随着你对Gin的深入学习和实践,你将能够利用它构建更复杂、更强大的Web应用。
|
6月前
|
SQL 安全 前端开发
Go语言Gin框架安全加固:全面解析SQL注入、XSS与CSRF的解决方案
Go语言Gin框架安全加固:全面解析SQL注入、XSS与CSRF的解决方案
|
6月前
|
Java Go 调度
Go语言并发编程原理与实践:面试经验与必备知识点解析
【4月更文挑战第12天】本文分享了Go语言并发编程在面试中的重要性,包括必备知识点和面试经验。核心知识点涵盖Goroutines、Channels、Select、Mutex、Sync包、Context和错误处理。面试策略强调结构化回答、代码示例及实战经历。同时,解析了Goroutine与线程的区别、Channel实现生产者消费者模式、避免死锁的方法以及Context包的作用和应用场景。通过理论与实践的结合,助你成功应对Go并发编程面试。
110 3
|
6月前
|
关系型数据库 MySQL Go
go语言使用Gin框架链接数据库
go语言使用Gin框架链接数据库
132 0
|
6月前
|
JavaScript 前端开发 NoSQL
go embed 实现gin + vue静态资源嵌入
go embed 实现gin + vue静态资源嵌入
437 0
|
6月前
|
中间件 Go
go 打印gin 中的c.Request的参数
在 Gin 框架中,可以通过 `c.Request` 获取请求对象,从而访问请求的参数。以下是一个示例,展示如何打印出 `c.Request` 中的参数: ```go package main import ( "fmt" "github.com/gin-gonic/gin" ) func LoggerMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 打印请求方法和路径 fmt.Printf("开始处理请求: %s %s\n", c.Request.Method, c.Request.URL.Pa
234 0