gin渲染
1. 各种数据格式的响应
- json、结构体、XML、YAML类似于java的properties、ProtoBuf
简单解释一下protobuf,在Golang中,Gin是一个流行的Web框架,而Protobuf(Protocol Buffers)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。结合Gin和Protobuf可以带来一些好处:
性能优化: 使用Protobuf可以减少数据传输的大小,提高数据传输效率,从而加快网络通信速度,减少带宽消耗。
代码生成: Protobuf提供了代码生成工具,可以根据定义的消息结构自动生成对应的数据结构和序列化/反序列化方法,简化开发过程。
类型安全: 使用Protobuf定义数据结构后,可以在编译阶段进行类型检查,避免一些潜在的数据传输错误。
易于维护: 由于Protobuf的消息结构是明确定义的,因此更易于维护和扩展。
在Gin框架中,结合Protobuf可以实现在HTTP接口中使用Protobuf数据作为请求和响应的载体,从而提高数据传输效率和代码的可维护性。通常情况下,你可以在Gin中使用Protobuf来定义接口的请求和响应数据结构,然后通过Protobuf提供的序列化和反序列化方法来处理这些数据,从而实现高效的数据传输和更清晰的代码结构。
package main
import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/testdata/protoexample"
)
type Login struct {
// 前端表格的名称对应的是form字段,表格的内容传入后端的json字段,
// binding 字段 设置为required 是必须的,不允许为空
User string ` uri:"user" `
Pssword string ` uri:"password" `
}
func main() {
r := gin.Default()
// 1.json
r.GET("/someJSON", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "JSON Message", "status": "200"})
})
// 2. 结构体响应
r.GET("/Sttuct", func(ctx *gin.Context) {
var msg struct {
Name string
Message string
Num int
}
msg.Name = "jack"
msg.Message = "hello"
msg.Num = 20
ctx.JSON(200, msg)
})
// xml
r.GET("/someXML", func(c *gin.Context) {
c.XML(200, gin.H{"type :": "XML"})
})
// yaml
r.GET("/someYAML", func(c *gin.Context) {
c.YAML(200, gin.H{"type :": "YAML"})
})
// protobuf格式,谷歌开发的高效存储读取的工具
// 数组?切片?如果自己构建一个传输格式,应该是什么格式?
r.GET("/ProtoBuf", func(ctx *gin.Context) {
reps := []int64{int64(1), int64(2)}
// 定义数据
label := "label"
// 传protobuf格式数据
data := &protoexample.Test{
Label: &label,
Reps: reps,
}
ctx.ProtoBuf(200, data)
})
r.Run()
}
2、HTML模板渲染
- gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数据,本质上就是字符串替换
- LoadHTMLGlob()方法可以加载模板文件
r := gin.Default()
// 加载模板文件
// 一级目录
r.LoadHTMLGlob("front/*")
r.GET("/index", func(c *gin.Context) {
c.HTML(200, "index.html", gin.H{"title": "我是大程", "msg": " 你好呀"})
})
// 相对于main来说是二级目录
r.LoadHTMLGlob("front/**/*")
r.GET("/index2", func(c *gin.Context) {
c.HTML(200, "user/index.html", gin.H{"title": "我是大程", "msg": " 你好呀"})
})
3、重定向
// 重定向
r.GET("/red", func(ctx *gin.Context) {
ctx.Redirect(http.StatusMovedPermanently, "http:www.51mb.com")
})
发生重定向
4、同步异步
- goroutine机制可以方便地实现异步处理
- 另外,在启动新的goroutine时,不应该使用原始上下文,必须使用它的只读副本
在Gin框架中,同步执行和异步执行是指处理HTTP请求的两种不同方式:
同步执行: 在同步执行中,每个HTTP请求都会在一个单独的goroutine中被处理。这意味着当一个请求到达时,Gin框架会为该请求创建一个goroutine来处理请求,直到请求处理完成并响应返回给客户端之后,该goroutine才会被释放。
异步执行: 在异步执行中,HTTP请求的处理不会阻塞主goroutine。相反,请求可能会被委托给另一个goroutine或者处理程序,并且主goroutine可以继续处理其他请求。异步执行通常通过goroutine和通道来实现,可以提高系统的并发性能和吞吐量。
在Gin框架中,默认情况下是同步执行的,即每个HTTP请求都会在一个goroutine中被处理。如果需要实现异步执行,可以在处理请求时手动启动goroutine来处理请求,或者使用Go语言的协程和通道机制来实现异步处理。
异步执行在处理大量请求或者需要长时间处理的请求时特别有用,因为它可以提高系统的并发能力和响应速度。但是需要注意在异步执行中要确保数据的正确性和避免竞态条件的发生
package main
import (
"log"
"time"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
//1. 异步
r.GET("/long_async", func(c *gin.Context) {
// 做一个副本
copyContext := c.Copy()
// 异步处理
go func() {
time.Sleep(time.Second)
log.Println("异步执行:" + copyContext.Request.URL.Path)
}()
})
// 2.同步
r.GET("/long_sync", func(ctx *gin.Context) {
time.Sleep(time.Second)
log.Println("同步执行:" + ctx.Request.URL.Path)
})
r.Run()
}