在采用 gin 框架写后端api时,经常会有嵌套形式的json串,如何使用golang进行序列化呢,此文实例详细说明。
实例json串结构如下:
{"data":
{ "userInfo":
{
"id":1,
"username":"admin",
"type":"0",
"status":"0",
"add_system_time":"1591434825",
"last_login_time":1629698073,
"remark":"super",
"created_at":null,
"updated_at":"2021-08-23 13:54:33",
"isbond":"1",
"secret":"Z4B7KBXK5C72SBGT"
},
"token":{
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC8xOTIuMTY4LjYxLjk1O...",
"expires_in":1629701673,
"refresh_expires_in":1630907673
}
}
}
采用定义 struct 结构,根据 json串的组织形式定义结构体,如下。
robot@ubuntu:~/go-workspace/src/mtk7621-api/user$ cat login.go
package Login
import (
"encoding/json"
"log"
"net/http"
"github.com/gin-gonic/gin"
)
type UserInfo struct {
ID int `json:"id"`
Username string `json:"username"`
Type string `json:"type"`
Status string `json:"status"`
AddSystemTime int `json:"add_system_time"`
LastLoginTime int `json:"last_login_time"`
Remark string `json:"remark"`
CreateAt string `json:"create_at"`
UpdatedAt string `json:"update_at"`
Isbond string `json:"isbond"`
Secret string `json:"secret"`
}
type Token struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshExpiresIn int `json:"refresh_expires_in"`
}
type ResData struct {
Uname *UserInfo `json:"userInfo"`
Tkn *Token `json:"token"`
}
type ResMsg struct {
Data *ResData `json:"data"`
}
func UserLogin(c *gin.Context) {
user := UserInfo{
ID:1,
Username: "admin",
Secret:"Z4B7KBXK5C72SBGT",
}
toke := Token{
AccessToken:"123456",
ExpiresIn: 1629701673,
RefreshExpiresIn:1629701673,
}
rdata := ResData{
Tkn:&toke,
Uname:&user,
}
msg := ResMsg{
Data:&rdata,
}
message, _ := json.Marshal(msg)
log.Println(string(message))
json := make(map[string]interface{})
c.BindJSON(&json)
log.Println("%v", &json)
c.JSON(http.StatusOK,string(message))
return
}
把结构体内容、通过 json.Marshal(msg) 序列化成json串,在把json串、转化成string对象,返回给vue前端。
~/go-workspace/src/mtk7621-api$ tree -L 2
.
├── api
├── bridge
├── go.mod
├── go.sum
├── interface
│ ├── DHCP
│ ├── DNS
│ ├── LTE
│ ├── POOL
│ ├── route
│ └── VLAN
├── ip
├── main.go
├── ppp
├── routing
├── system
├── tools
└── user
└── login.go
14 directories, 5 files
package main
import (
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
"golang.org/x/sync/errgroup"
"api/user" //调用 user 包, 此user是文件夹
)
var (
g errgroup.Group
)
// api context
var user_login string = "/api/user/login" // 接口路由
func http_api() http.Handler {
e := gin.New()
e.POST(user_login,Login.UserLogin) //调用 Login 包中的函数 UserLogin
return e
}
func http_eapi() http.Handler {
e := gin.New()
e.POST(user_login, func(c *gin.Context) {
c.JSON(
http.StatusOK,
gin.H{
"code": http.StatusOK,
"error": "Welcome server 02",
},
)
})
return e
}
func main() {
http_api := &http.Server{
Addr: ":8080",
Handler: http_api(),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
http_eapi := &http.Server{
Addr: ":8081",
Handler: http_eapi(),
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
}
g.Go(func() error {
return http_api.ListenAndServe()
})
g.Go(func() error {
return http_eapi.ListenAndServe()
})
if err := g.Wait(); err != nil {
log.Fatal(err)
}
}
编译源码
robot@ubuntu:~/go-workspace/src/mtk7621-api$ go build .
运行
robot@ubuntu:~/go-workspace/src/mtk7621-api$ ./api
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /api/user/login --> api/user.UserLogin (1 handlers)
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /api/user/login --> main.http_eapi.func1 (1 handlers)
// 返回的data的json 串内容
2021/08/25 01:55:09 {"data":{"userInfo":{"id":1,"username":"admin","type":"","status":"","add_system_time":0,"last_login_time":0,"remark":"","create_at":"","update_at":"","isbond":"","secret":"Z4B7KBXK5C72SBGT"},"token":{"access_token":"123456","expires_in":1629701673,"refresh_expires_in":1629701673}}}
// vue 发送过来的json 串内容
2021/08/25 01:55:09 %v &map[code: password:abcde username:12345]
[GIN-debug] redirecting request 307: /api/menu/menu/ --> /api/menu/menu/
[GIN-debug] redirecting request 307: /api/menu/menu/ --> /api/menu/menu/
2021/08/25 03:28:04 {"data":{"userInfo":{"id":1,"username":"admin","type":"","status":"","add_system_time":0,"last_login_time":0,"remark":"","create_at":"","update_at":"","isbond":"","secret":"Z4B7KBXK5C72SBGT"},"token":{"access_token":"123456","expires_in":1629701673,"refresh_expires_in":1629701673}}}
2021/08/25 03:28:04 %v &map[code: password:123456 username:admin]
[GIN-debug] redirecting request 307: /api/menu/menu/ --> /api/menu/menu/
2021/08/25 03:28:38 {"data":{"userInfo":{"id":1,"username":"admin","type":"","status":"","add_system_time":0,"last_login_time":0,"remark":"","create_at":"","update_at":"","isbond":"","secret":"Z4B7KBXK5C72SBGT"},"token":{"access_token":"123456","expires_in":1629701673,"refresh_expires_in":1629701673}}}
2021/08/25 03:28:38 %v &map[code: password:123 username:admin]
[GIN-debug] redirecting request 307: /api/menu/menu/ --> /api/menu/menu/