15、Go Gin常见响应返回详解

一、各种数据格式的响应

  • json、结构体、XML、YAML类似于java的properties、ProtoBuf
Go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/testdata/protoexample"
)

// 多种响应方式
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": 200})
	})

	// 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(200, 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")
}

2、JSON响应

3、结构体响应

4、XML

  • http://localhost:8000/someXML

    This XML file does not appear to have any style information associated with it. The document tree is shown below.<map><message>abc</message></map>

5、YAML响应

二、重定向

Go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	r := gin.Default()
	r.GET("/index", func(c *gin.Context) {
		
		//状态码为 30(永久重定向)
		c.Redirect(http.StatusMovedPermanently, "redirect-to-baidu")
	})

	// 定义一个路由,当访问这个路由时,会重定向到百度首页
	r.GET("/redirect-to-baidu", func(c *gin.Context) {
		// 百度首页的URL
		baiduURL := "http://www.baidu.com"

		// 重定向到百度首页,状态码为 302(临时重定向)
		c.Redirect(http.StatusFound, baiduURL)
	})
	r.Run()
}

三、同步异步

  • goroutine机制可以方便地实现异步处理

  • 另外,在启动新的goroutine时,不应该使用原始上下文,必须使用它的只读副本

Go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"log"
	"time"
)

func main() {
	// 1.创建路由
	// 默认使用了2个中间件Logger(), Recovery()
	r := gin.Default()

	// 1.同步
	r.GET("/long_sync", func(c *gin.Context) {
		time.Sleep(3 * time.Second)
		log.Println("同步执行:" + c.Request.URL.Path)
		c.JSON(200, gin.H{"message": "同步执行", "status": 200})
	})

	// 2.异步
	r.GET("/long_async", func(c *gin.Context) {
		// 异步处理,需要搞一个副本
		copyContext := c.Copy()
		go func() {
			time.Sleep(3 * time.Second)
			log.Println("异步执行:" + copyContext.Request.URL.Path)
		}()
		// 异步处理允许服务器在处理请求时,不必等待当前请求完成就可以响应。
		c.JSON(200, gin.H{"message": "异步执行", "status": 200})
	})
	r.Run(":8000")
}
使用 c.Next()

c.Next() 允许你继续执行中间件链中的下一个中间件,但不会结束当前的请求处理。这可以用来在中间件中执行一些异步操作,而不影响请求的继续处理。

Go 复制代码
package main

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

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

	router.Use(func(c *gin.Context) {
		// 执行一些异步操作
		go func() {
			// 异步任务
		}()

		c.Next() // 继续执行下一个中间件或处理函数
	})

	router.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "pong"})
	})

	router.Run()
}
使用 c.Abort()

c.Abort() 用于立即结束当前的请求处理,并可以返回一个响应给客户端。这通常用于在中间件中检测到某些条件不满足时,提前结束请求处理。

Go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

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

	router.Use(func(c *gin.Context) {
		if 1 > 0 { //中间件中检
			c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "xxx无权限"})
			return
		}

		c.Next() // 如果条件满足,继续执行
	})

	router.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{"message": "pong"})
	})

	router.Run()
}
相关推荐
kite01213 小时前
Gin + Zap 日志:构建高性能、结构化的应用日志系统
golang·gin·log·zap
OxYGC4 小时前
[玩转GoLang] 5分钟整合Gin / Gorm框架入门
开发语言·golang·gin
张烫麻辣亮。1 天前
golang-gin包
开发语言·golang·gin
小红帽2.03 天前
GOFLY开源客服系统-处理gin框架下的session中间件
中间件·gin
小红帽2.04 天前
从零搭建客服系统:我是如何用Gin实现页面路由与模板渲染的
gin
戎码江湖4 天前
使用CI/CD部署后端项目(gin)
ci/cd·golang·gin·后端自动部署项目·自动化部署项目
夏沫mds11 天前
【基于hyperledger fabric的教育证书管理系统】
运维·go·vue·区块链·gin·fabric
水墨熊猫12 天前
【FIX】go运行报错“missing go.sum entry for module providing package”解决方案
golang·gin
用户895356032822015 天前
告别重复,用Go泛型精简Gin代码
后端·gin
水痕0123 天前
gin结合minio来做文件存储
java·eureka·gin