3

基于Gin框架的web开发,总的来讲有两种:

  • 第一种是后端使用go语言模板引擎完成整个web全栈开发,返回完整的html文件给浏览器。
  • 第二种是前后端分离,使用JSON交互

由于第一种方法耗费太多网络资源,性能差,耦合度高,目前已经基本被第二种模式取代,这篇博客只介绍如何在Gin框架中返回JSON数据给前端或者移动端(俗称JSON的渲染)。


生成JSON数据可以用map,也可以用结构体。下面先介绍map:

基于map的JSON数据生成

举个例子,代码如下:

package main

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

func main() {
    r := gin.Default()
    r.GET("/json", func(c *gin.Context) {
        //这里构造服务器要返回前端的数据,一共有两种方法,第一种是:使用map将数据序列化
        //,这个map的key是一个string, value是一个空的接口(这样即可以实现接收任意类型的数据)
        data := map[string]interface{}{
            "name":    "liber",
            "message": "hey liber~",
            "age":     16,
        }
        //这里要返回json格式的数据,所以用c.JSON,这样,数据就返回给请求方了
        c.JSON(http.StatusOK, data)
    })
    r.Run(":9090")
}

测试结果如下:

由于用map来序列化json数据是很常见的写法,Gin框架的作者将这种写法封装了一下:

//H is a shortcut for map[string]interface{}
type H map[string]interface{}

所以,我们可以直接使用gin.H{}来代替:

package main

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

func main() {
    r := gin.Default()
    r.GET("/json", func(c *gin.Context) {
        //这里构造服务器要返回前端的数据,一共有两种方法,第一种是:使用map将数据序列化
        //,这个map的key是一个string, value是一个空的接口(这样即可以实现接收任意类型的数据)
        //data := map[string]interface{}{
        //    "name":    "liber",
        //    "message": "hey liber~",
        //    "age":     16,
        //}
        data := gin.H{
            "name":    "libro",
            "message": "hey libro~",
            "age":     17,
        }
        //这里要返回json格式的数据,所以用c.JSON,这样,数据就返回给请求方了
        c.JSON(http.StatusOK, data)
    })
    r.Run(":9090")
}

测试结果如下:

基于结构体的JSON数据生成

其实就是另一种写法而已:

package main

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

func main() {
    r := gin.Default()
    r.GET("/json", func(c *gin.Context) {
        //这里构造服务器要返回前端的数据,一共有两种方法,第一种是:使用map将数据序列化
        //,这个map的key是一个string, value是一个空的接口(这样即可以实现接收任意类型的数据)
        //data := map[string]interface{}{
        //    "name":    "liber",
        //    "message": "hey liber~",
        //    "age":     16,
        //}
        data := gin.H{
            "name":    "libro",
            "message": "hey libro~",
            "age":     17,
        }
        //这里要返回json格式的数据,所以用c.JSON,这样,数据就返回给请求方了
        c.JSON(http.StatusOK, data)
    })

    //这里介绍生成JSON数据的第二种方法:利用结构体
    //首先构造一个结构体
    type msg struct {
        Name    string
        Message string
        Age     int
    }
    //然后构建一个结构体的实例
    r.GET("/another_json", func(c *gin.Context) {
        data := msg{
            Name:    "libro",
            Message: "hey libro~",
            Age:     17,
        }
        c.JSON(http.StatusOK, data)
    })
    r.Run(":9090")
}

测试结果如图:

不过需要注意的是,如果使用结构体,字段开头字母必须大写,否则就没办法完成JSON的序列化,因为JSON序列化过程中使用到了Go内置的反射机制,小写表示不可导出。当然这也有解决之道,就是打tag:

//这里假设 前端就需要小写的name
    type msg struct {
        Name    string `json: "name"`
        Message string
        Age     int
    }

其实我觉得,既然有坑,直接规定用第一种方法规避掉是一种简洁&明智的选择。


参考: bilibili

LiberHome
409 声望1.1k 粉丝

有问题 欢迎发邮件 📩 liberhome@163.com