官方文档地址(中文):https://gin-gonic.com/zh-cn/docs/
注:本教程采用工作区机制,所以一个项目下载了Gin框架,其余项目就无需重复下载,想了解的读者可阅读第一节:Gin操作指南:开山篇。
本节演示JSON渲染,包括AsciiJSON JSONP PureJSON SecureJSON XML-JSON-YAML-ProtoBuf渲染。在开始之前,我们需要在”01数据渲染“目录下打开命令行,执行如下命令来创建子目录:
mkdir AsciiJSON JSONP PureJSON SecureJSON XML-JSON-YAML-ProtoBuf渲染
目录
- 一、AsciiJSON
- 二、JSONP
- 三、PureJSON
- 四、SecureJSON
- 五、XML-JSON-YAML-ProtoBuf渲染
一、AsciiJSON
在”AsciiJSON“根目录下创建main.go,填充代码:
package main
import (
"net/http" // 用于提供 HTTP 标准响应状态码,如 http.StatusOK
"github.com/gin-gonic/gin" // 引入 Gin Web 框架的包
)
func main() {
// 创建一个默认的 Gin 路由器,带有默认的日志记录和恢复中间件(可自动记录每个请求并处理崩溃恢复)
r := gin.Default()
// 定义一个 GET 请求的路由 `/someJSON`
// 当客户端发起对 "/someJSON" 的 GET 请求时,执行回调函数处理请求
r.GET("/someJSON", func(c *gin.Context) {
// 准备一个包含两对键值对的数据结构,用于返回 JSON 响应
data := map[string]interface{}{
"lang": "GO语言", // 第一个键值对,lang 对应的是 "GO语言"
"tag": "<br>", // 第二个键值对,tag 对应的是 HTML 标签 "<br>"
}
// 使用 AsciiJSON 方法生成 ASCII-only 的 JSON 响应
// 非 ASCII 字符会被转义,例如 "GO语言" 中的 "语言" 会被转义为 Unicode 格式:\u8bed\u8a00
// 同样的,"<br>" 会被转义为 \u003cbr\u003e
// 输出结果将会是: {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
c.AsciiJSON(http.StatusOK, data)
})
// 启动 HTTP 服务,监听 0.0.0.0:8080 地址
// 这个地址意味着服务将在本地所有可用的 IP 地址上监听请求
// 默认的端口是 8080,如果需要使用不同的端口,修改 ":8080" 为其他值即可
r.Run(":8080")
}
gin.Context
: gin.Context 是 Gin 框架中用于处理请求和响应的核心数据结构。通过它,开发者可以读取请求参数、设置响应数据,以及管理 HTTP 状态码等。
效果:
二、JSONP
在”JSONP“根目录下创建main.go,填充代码:
package main
import (
"net/http" // 导入 http 包,用于定义 HTTP 状态码
"github.com/gin-gonic/gin" // 引入 Gin Web 框架
)
func main() {
// 创建一个默认的 Gin 路由引擎实例,默认启用 Logger 和 Recovery 中间件
r := gin.Default()
// 定义一个 GET 路由,当用户访问 /JSONP 时触发该处理函数
r.GET("/JSONP", func(c *gin.Context) {
// 定义一个 map 类型的变量 data,存储要返回给客户端的 JSON 数据
// 键为字符串类型,值为 interface{},可以存储任意类型的数据
data := map[string]interface{}{
"foo": "bar", // "foo" 字段的值为 "bar"
}
// 如果用户访问的 URL 包含查询参数 callback,例如 /JSONP?callback=x
// Gin 会将 JSON 数据封装到指定的回调函数中
// 输出格式将会是 x({"foo":"bar"}), 其中 x 是用户提供的回调函数名
c.JSONP(http.StatusOK, data)
})
// 启动 HTTP 服务器并监听在 0.0.0.0:8080 上
// 0.0.0.0 表示服务器监听所有网络接口,端口为 8080
r.Run(":8080")
}
效果:
三、PureJSON
在”PureJSON“根目录下创建main.go,填充代码:
package main
import (
"github.com/gin-gonic/gin" // 引入 Gin Web 框架
)
func main() {
// 创建一个默认的 Gin 路由引擎实例,启用 Logger 和 Recovery 中间件
r := gin.Default()
// 定义一个 GET 路由,当用户访问 /json 时执行该处理函数
// 该处理函数使用标准的 c.JSON 方法输出 JSON 数据
// 该方法会将 HTML 标签转义为 Unicode 码点
r.GET("/json", func(c *gin.Context) {
// 使用 c.JSON 生成 JSON 响应,自动将特殊字符转义
// 例如 <b>Hello, world!</b> 将被转义为 "\u003cb\u003eHello, world!\u003c/b\u003e"
c.JSON(200, gin.H{
"html": "<b>Hello, world!</b>", // 这个字符串会被自动转义
})
})
// 定义另一个 GET 路由,当用户访问 /purejson 时执行该处理函数
// 该处理函数使用 PureJSON 方法,直接输出原始字符,不进行转义
r.GET("/purejson", func(c *gin.Context) {
// 使用 c.PureJSON 生成不转义的 JSON 响应
// 例如 <b>Hello, world!</b> 将保持原样输出,不会被转义
c.PureJSON(200, gin.H{
"html": "<b>Hello, world!</b>", // 这个字符串将以原始形式返回,不进行转义
})
})
// 启动 HTTP 服务器并监听 0.0.0.0:8080,表示接受所有网络接口上的请求
r.Run(":8080")
}
效果:
四、SecureJSON
在”SecureJSON“根目录下创建main.go,填充代码:
package main
import (
"net/http" // 导入 HTTP 标准库,用于处理 HTTP 请求和响应
"github.com/gin-gonic/gin" // 引入 Gin Web 框架
)
func main() {
// 创建一个默认的 Gin 路由引擎实例,启用 Logger 和 Recovery 中间件
r := gin.Default()
// 你也可以自定义 SecureJSON 的前缀
// 通过 r.SecureJsonPrefix(")]}',\n") 可以为返回的 JSON 添加自定义前缀
// 默认情况下,Gin 会添加 "while(1);" 作为前缀
// r.SecureJsonPrefix(")]}',\n") // 这里注释掉了自定义前缀的设置
// 定义一个 GET 路由,当用户访问 /someJSON 时执行该处理函数
r.GET("/someJSON", func(c *gin.Context) {
// 定义一个包含名字的字符串数组
names := []string{"lena", "austin", "foo"}
// 使用 c.SecureJSON 返回数组数据,并在响应中添加防止 JSON 劫持的前缀
// 输出的响应将会是:while(1);["lena","austin","foo"]
// "while(1);" 是默认的前缀,用于阻止恶意脚本解析此 JSON 数据
c.SecureJSON(http.StatusOK, names)
})
// 启动 HTTP 服务器并监听 0.0.0.0:8080,表示接受所有网络接口上的请求
r.Run(":8080")
}
效果:
五、XML-JSON-YAML-ProtoBuf渲染
在”XML-JSON-YAML-ProtoBuf渲染“根目录下创建main.go,填充代码,效果和之前没有本质区别,故省略。
package main
import (
"net/http" // 标准库的 net/http 包,用于处理 HTTP 请求和响应
"github.com/gin-gonic/gin" // 引入 Gin Web 框架
)
func main() {
// 创建一个默认的 Gin 路由引擎实例,启用 Logger 和 Recovery 中间件
r := gin.Default()
// 定义一个 GET 路由,当用户访问 /someJSON 时,返回 JSON 格式的数据
r.GET("/someJSON", func(c *gin.Context) {
// 使用 gin.H,这是 Gin 框架提供的 map[string]interface{} 的快捷方式
// 返回一个 JSON 对象,包含两个键值对:message 和 status
c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
// 定义一个 GET 路由,返回结构化的 JSON 数据
r.GET("/moreJSON", func(c *gin.Context) {
// 定义一个结构体来包含要返回的数据
var msg struct {
Name string `json:"user"` // 使用 `json` 标签指定 JSON 字段名为 "user"
Message string // 没有标签时,字段名按原样使用
Number int
}
// 为结构体字段赋值
msg.Name = "Lena"
msg.Message = "hey"
msg.Number = 123
// 返回结构化的 JSON 数据,Gin 会自动将结构体序列化为 JSON
// 输出将是 {"user": "Lena", "Message": "hey", "Number": 123}
c.JSON(http.StatusOK, msg)
})
// 定义一个 GET 路由,返回 XML 格式的数据
r.GET("/someXML", func(c *gin.Context) {
// 使用 gin.H 方式返回 XML 数据
// 输出格式类似于:<map><message>hey</message><status>200</status></map>
c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
// 定义一个 GET 路由,返回 YAML 格式的数据
r.GET("/someYAML", func(c *gin.Context) {
// 使用 gin.H 返回 YAML 格式的数据
// 输出将是:message: hey\nstatus: 200\n
c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
})
// 定义一个 GET 路由,返回 Protobuf 序列化后的数据
/*
如果你要在 Gin 项目中使用 Protobuf,你需要:
安装 Protocol Buffers 编译器 protoc。
安装 protoc-gen-go 插件:
bash
复制代码
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
定义 .proto 文件,使用 protoc 工具生成 Go 代码。
在 Gin 中使用 c.ProtoBuf 来发送序列化的 Protobuf 响应。
*/
// r.GET("/someProtoBuf", func(c *gin.Context) {
// // 构造 Protobuf 数据
// reps := []int64{int64(1), int64(2)} // 定义一个 int64 类型的切片
// label := "test" // 定义一个标签
// // 使用 protoexample.Test 结构体,这是 Protobuf 生成的结构
// data := &protoexample.Test{
// Label: &label, // 设置 Label 字段
// Reps: reps, // 设置 Reps 字段
// }
// // 使用 c.ProtoBuf 返回 Protobuf 序列化后的数据,响应类型为二进制
// // 输出的数据是经过 protoexample.Test 定义的 Protobuf 格式
// c.ProtoBuf(http.StatusOK, data)
// })
// 启动 HTTP 服务器并监听 0.0.0.0:8080,表示接受所有网络接口上的请求
r.Run(":8080")
}