Gin框架完全使用指南 | Gin框架多种数据格式响应

公众号:程序员读书,欢迎关注

Gin支持多种数据格式的响应,如:JSON(JSON,SecureJSON,JSONP,AsciiJSON,PureJSON,IndentedJSON)XMLYAMLTOMLProtoBuf等。

同时也支持返回HTML模板静态文件或者返回文件系统中的文件,甚至可以把实现了io.Reader接口的对象作为响应。

JSON

除了正常JSON数据格式,Gin还支持多种格式的JSON输出,如SecureJSON,JSONP,AsciiJSON,PureJSON,IndentedJSON

  • SecureJSON:预防JSON数组劫持。
  • JSONP:与script标签配合使用,可以不受浏览器跨域限制。
  • AsciiJSON:将JSON数据中非ASCII转化为ASCII码。
  • PureJSON:不转换HTML标签。
  • IndentedJSON:对齐输出。
go 复制代码
 package main
 ​
 import (
   "net/http"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 type User struct {
   Id     int
   Name   string
   Habits []string
 }
 ​
 func main() {
   engine := gin.New()
 ​
   u := User{Id: 1, Name: "小明", Habits: []string{"看书", "看电影"}}
 ​
   engine.GET("/JSON", func(ctx *gin.Context) {
     ctx.JSON(http.StatusOK, u)
   })
 ​
   engine.GET("/JSONP?callback=test", func(ctx *gin.Context) {
     ctx.JSONP(http.StatusOK, u)
   })
 ​
   engine.GET("/AsciiJSON", func(ctx *gin.Context) {
     ctx.AsciiJSON(http.StatusOK, u)
   })
 ​
   engine.GET("/IndentedJSON", func(ctx *gin.Context) {
     ctx.IndentedJSON(http.StatusOK, u)
   })
 ​
   engine.GET("/PureJSON", func(ctx *gin.Context) {
     ctx.PureJSON(http.StatusOK, u)
   })
 ​
   engine.GET("/SecureJSON", func(ctx *gin.Context) {
     data := []int{1, 2, 3, 4}
     ctx.SecureJSON(http.StatusOK, data)
   })
 ​
   engine.Run()
 }

XML

要响应XML格式可以调用gin.Contextxml方法,此时Content-Typeapplication/xml

go 复制代码
 package main
 ​
 import (
   "encoding/xml"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 type User struct {
   XMLName xml.Name `xml:"user"`
   Id      int      `xml:"id"`
   Name    string   `xml:"name"`
   Habits  []string `xml:"habits"`
 }
 ​
 func main() {
 ​
   engine := gin.New()
 ​
   engine.GET("/xml", func(ctx *gin.Context) {
     user := &User{Id: 1, Name: "小明", Habits: []string{"看书", "看电影"}}
     ctx.XML((http.StatusOK, user)
   })
 ​
   engine.Run()
 }

TOML

要响应TOML格式可以调用gin.Contexttoml方法,此时Content-Typeapplication/toml

go 复制代码
 package main
 ​
 import (
   "net/http"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 type User struct {
   Id     int
   Name   string
   Habits []string
 }
 ​
 func main() {
 ​
   engine := gin.New()
 ​
   engine.GET("/toml", func(ctx *gin.Context) {
     user := &User{Id: 1, Name: "小明", Habits: []string{"看书", "看电影"}}
     ctx.TOML(http.StatusOK, user)
   })
 ​
   engine.Run()
 }
 ​

YAML

要响应YAML格式可以调用gin.Contextyaml方法,此时Content-Typeapplication/yaml

go 复制代码
 package main
 ​
 import (
   "net/http"
 ​
   "github.com/gin-gonic/gin"
 )
 ​
 type User struct {
   Id     int
   Name   string
   Habits []string
 }
 ​
 func main() {
 ​
   engine := gin.New()
 ​
   engine.GET("/yaml", func(ctx *gin.Context) {
     user := &User{Id: 1, Name: "小明", Habits: []string{"看书", "看电影"}}
     ctx.YAML(http.StatusOK, user)
   })
 ​
   engine.Run()
 }

ProtoBuf

要响应ProtoBuf格式的数据,首先要定义proto文件:

ini 复制代码
 syntax = "proto3";
 ​
 option go_package = "./user";
 ​
 message User {
     int64  Id = 1;
     string Name = 2;
     string Email = 3;
 }

定义好proto文件调用protoc命令文件生成pb文件:

注意,运行protoc命令提交安装好protocprotoc-gen-go

css 复制代码
 $ protoc --proto_path=./ --go_out=./ ./user.proto

执行命令后,此时项目目录结构如下:

go 复制代码
 ├── main.go
 ├── user
 │   └── user.pb.go
 └── user.proto

调用gin.ContextProtoBuf方法响应数据:

go 复制代码
 package main
 ​
 import (
   "user"
   "github.com/gin-gonic/gin"
 )
 ​
 func main() {
   router := gin.New()
   router.GET("/protoBuf", func(ctx *gin.Context) {
     u := user.User{Id: 1, Name: "protoBuf", Email: "test@163.com"}
     ctx.ProtoBuf(http.StatusOK, &u)
   })
   router.Run()
 }

HTML模板

要响应HTML模板可以调用gin.ContextHTML方法,不过要提前加载模板,假设我们有一个模板名称为templates/index.tmpl,其内容如下:

css 复制代码
<html>
	<h1>
		{{ .title }}
	</h1>
</html>

使用gin.EngineLoadHTMLFiles()可以加载一个或多个HTML模板:

css 复制代码
package main 

func main() {
	engine := gin.Default()
	engine.LoadHTMLFiles("templates/index.tmpl")
	engine.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.tmpl", gin.H{
			"title": "主页",
		})
	})
	engine.Run()
}

也可以使用gin.EngineLoadHTMLGlob()加载整个目录的HTML模板:

css 复制代码
package main 

func main() {
	engine := gin.Default()
	engine.LoadHTMLGlob("templates/**/*")
	engine.GET("/index", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "index.tmpl", gin.H{
			"title": "主页",
		})
	})
	engine.Run()
}

静态文件

除了正常响应格式,还可以StaticStaticFile设置静态文件(如jscss等)响应:

arduino 复制代码
├── main.go
└── static
    ├── js
    │   └── index.js
    └── pages
        └── index.html

假设项目目录格式如上所示,此时我们可以按下面代码加载静态文件:

css 复制代码
package main

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

func main() {
	engine := gin.New()
	engine.Static("static/pages", "./static/pages")
	engine.StaticFile("/static/js/index.js", "./static/js/index.js")
	engine.Run()
}

小结

Gin支持多种数据格式响应,我们可以根据自己的需求选择对应的数据格式。

相关推荐
To_OC6 小时前
手写 AI 编程 Agent 的命令执行工具:我被 child_process 坑出来的实战经验
后端·node.js·agent
逝水无殇9 小时前
C# 异常处理详解
开发语言·后端·c#
考虑考虑11 小时前
Sentinel安装
java·后端·微服务
IT_陈寒11 小时前
SpringBoot自动配置失灵?你可能忘了这个关键注解
前端·人工智能·后端
碎碎念_49211 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
逝水无殇11 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
YIAN12 小时前
从手写 Agent 工具到 MCP 协议:一文搞懂大模型跨进程跨语言工具调用
后端·agent·mcp
小兔崽子去哪了12 小时前
Docker 删除镜像后磁盘空间没有释放?
后端·docker·容器
高明珠13 小时前
麒麟 V10 SP1 排查实录:ttyS5 每 10 秒莫名收到一批报文,元凶是 eGTouchD
后端
卷无止境13 小时前
Python FFI 技术深度解析:ctypes、cffi 与 pybind11 的性能差异与实践挑战
后端·python