gin框架(三)gin 渲染|青训营笔记

425 阅读3分钟

在 Gin框架中,对 HTTP请求可以很方便有多种不同形式的响应。比如响应为 JSON 、 XML或者是 HTML 等。

内容序列化

Context的以下方法在Gin框架中把内容序列化为不同类型写入到响应主体中。

func (c *Context) HTML(code int, name string, obj interface{})

// IndentedJSON 将给定结构序列化为漂亮的 JSON(缩进+结束行)到响应体中。
// 同时将 Content-Type设置为 “application/json”。
// 警告:建议仅将此用于开发目的,因为打印漂亮的 JSON 会占用更多 CPU 和带宽。
// 请改用 Context.JSON() 。
func (c *Context) IndentedJSON(code int, obj interface{})

// SecureJSON 将给定结构序列化为安全 JSON 到响应主体中。
// 如果给定的结构是数组值,则默认将 “while(1)” 添加到响应主体。
// 将 Content-Type设置为 “application/json” 。
func (c *Context) SecureJSON(code int, obj interface{})

// JSONP 将给定结构序列化为 JSON 到响应体中。
// 它可跨域向服务器请求数据。
// 将 Content-Type 设置为 “application/javascript” 。
func (c *Context) JSONP(code int, obj interface{})

// JSON 将给定结构序列化为 JSON 到响应主中。
// 将 Content-Type 设置为 “application/json” 。
func (c *Context) JSON(code int, obj interface{})

// AsciiJSON 将给定结构作为 JSON 序列化到响应体中,并将 Unicode 序列化为 ASCII 字符串。
// 将 Content-Type 设置为 “application/json” 。
func (c *Context) AsciiJSON(code int, obj interface{})

// PureJSON 将给定结构序列化为 JSON 到响应体中。
// 与 JSON 不同,PureJSON 不会用他们的 Unicode 实体替换特殊的 HTML 字符。
func (c *Context) PureJSON(code int, obj interface{})

// XML 将给定结构序列化为 XML 到响应体中。
// 将 Content-Type 设置为 “application/xml” 。
func (c *Context) XML(code int, obj interface{})

// YAML 将给定结构序列化为 YAML 到响应体中。
func (c *Context) YAML(code int, obj interface{})

// ProtoBuf 将给定结构序列化为 ProtoBuf 到响应体中。
func (c *Context) ProtoBuf(code int, obj interface{})

// String 将给定字符串写入到响应体中。
func (c *Context) String(code int, format string, values ...interface{})

// Redirect 将 HTTP 重定向返回到特定位置。
func (c *Context) Redirect(code int, location string)

// Data 将一些数据写入正文流并更新 HTTP 状态代码。
func (c *Context) Data(code int, contentType string, data []byte)

// DataFromReader 将指定的读取器写入正文流并更新 HTTP 代码。
func (c *Context) DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string)

// File 以有效的方式将指定的文件写入正文流。
func (c *Context) File(filepath string)

// FileAttachment 以有效的方式将指定的文件写入正文流中在客户端,
// 通常会使用给定的文件名下载该文件。
func (c *Context) FileAttachment(filepath, filename string)

// SSEvent 将 Server-Sent 事件写入正文流。
func (c *Context) SSEvent(name string, message interface{})

// Stream 发送流响应并返回布尔值,表示“客户端在流中间断开连接”。
func (c *Context) Stream(step func(w io.Writer) bool) bool

各种数据格式的响应

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")
}

HTML模板渲染

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

image.png

重定向

image.png

重定向返回一个HTTP重定向到特定的位置。

同步异步

  • goroutine机制可以方便地实现异步处理
  • 另外,在启动新的goroutine时,不应该使用原始上下文,必须使用它的只读副本

image.png