go不定义结构体解析json

背景

系统自带的 Json.Marshal / Json.Unmarshal 需要定义一个结构体,json比较简单的时候就很好用,对于以下复杂的类型,就不太合适

{
    "userInfo":{
        "userId":"100021",
        "deviceCode":"1111"
    },
    "answerInfos":[
        {
            "question":"基价",
            "standardQuestion":"查基价",
            "questionId":"1452128",
            "isHit":1,
            "relatedQuestions":[
                "基价"
            ],
            "sessionId":"e455af0986d24c2daa2cdc50d62cec60",
            "answerCoded":"您要看哪个城市?&{R_001_001|ctg:中厚板|time:}",
            "answer":"您要看哪个城市?",
            "isChart":0,
            "chartId":"1434187",
            "isContinuous":1,
            "isLast":0,
            "tips":[
                "冷轧",
                "热轧",
                "中厚板",
                "低合金"
            ],
            "answerSource":"XIAO_I",
            "expandInfo":{
                "text":"查看更多",
                "url":"http://baidu.com"
            },
            "isCard":1,
            "cardCode":"CARD_001",
            "cardInfo":"{"buttonName":"查看订单","cardCode":"CARD_001","cardName":"打开订单","loginCheck":1,"operationCode":"H5","operationValue":"http:我的订单","tips":["可以点击【我的订单】【申请提货】按钮提货","可以点击【我的订单】【申请提货】按钮提货"],"titleContext":"您可点击下方按钮进入【我的订单】页面进行提货"}"
        }
    ],
    "resCode":0,
    "errorMsg":"成功"
}

解决思路

  1. 通过 map[string]interface{}
  2. 使用反射和Interface,开源库simplejson就是这样干的。https://github.com/bitly/go-simplejson

这里使用simplejson去做。

simplejson库

https://godoc.org/github.com/bitly/go-simplejson
1.import

import "github.com/bitly/go-simplejson"

2.new

var j *simplejson.Json
j, err = simplejson.NewJson(data)
if err != nil {
	logger.Sugar.Warnf("NewJson error:%s", err.Error())
	return
}

3.此时就可以读取了

// 获取 answerInfos 节点
answerNode := j.Get("answerInfos")

// 节点是数组,没有名字,可用索引获取
node1 := answerNode.GetIndex(0)

// 获取question字段
q := node1.Get("question").MustString()

4.完整代码

package main

import (
	"encoding/json"
	"fmt"
	"github.com/bitly/go-simplejson"
)

func main() {
	data := []byte(`
{
	"userInfo": {
		"userId": "100021",
		"deviceCode": "1111"
	},
	"answerInfos": [{
		"question": "基价",
		"standardQuestion": "查基价",
		"questionId": "1452128",
		"isHit": 1,
		"relatedQuestions": [
			"基价"
		],
		"sessionId": "e455af0986d24c2daa2cdc50d62cec60",
		"answerCoded": "您要看哪个城市?&{R_001_001|ctg:中厚板|time:}",
		"answer": "您要看哪个城市?",
		"isChart": 0,
		"chartId": "1434187",
		"isContinuous": 1,
		"isLast": 0,
		"tips": [
			"冷轧",
			"热轧",
			"中厚板",
			"低合金"
		],
		"answerSource": "XIAO_I",
		"expandInfo": {
			"text": "查看更多",
			"url": "http://baidu.com"
		},
		"isCard": 1,
		"cardCode": "CARD_001",
		"cardInfo": {
			"buttonName": "查看订单",
			"cardCode": "CARD_001",
			"cardName": "打开订单",
			"loginCheck": 1,
			"operationCode": "H5",
			"operationValue": "http:我的订单",
			"tips": [
				"可以点击【我的订单】【申请提货】按钮提货",
				"可以点击【我的订单】【申请提货】按钮提货"
			],
			"titleContext": "您可点击下方按钮进入【我的订单】页面进行提货"
		}
	}],
	"resCode": 0,
	"errorMsg": "成功"
}
`)

	var j *simplejson.Json
	j, err := simplejson.NewJson(data)
	if err != nil {
		fmt.Print("NewJson error:", err.Error())
		return
	}

	// 获取 answerInfos 节点
	answerNode := j.Get("answerInfos")

	// answerInfos 下面是一个数组
	// rows是 []interface{},类型
	rows, err := answerNode.Array()
	if err != nil {
		fmt.Print("Get answerInfos error:", err.Error())
		return
	}

	// 打印answerInfos下数组长度,这里只有1个节点,所以是1
	fmt.Printf("answerInfos size:%d \n", len(rows))

	// row是interface{}类型
	for index, row := range rows {
		// rows是数组,所以需要再获取一下节点
		node := answerNode.GetIndex(index)

		question := node.Get("question").MustString()
		answer := node.Get("answer").MustString()

		fmt.Printf("q:%s,a:%s \n", question, answer)

		// row是interface{}类型,可以调用系统方法,再转换成一段json
		data, err := json.Marshal(row)
		if err == nil {
			fmt.Printf("answerInfos[%d]=%s", index, string(data))
		}
	}
}

输出

answerInfos size:1 
q:基价,a:您要看哪个城市? 
answerInfos[0]={"answer":"您要看哪个城市?","answerCoded":"您要看哪个城市?\u0026{R_001_001|ctg:中厚板|time:}","answerSource":"XIAO_I","cardCode":"CARD_001","cardInfo":{"buttonName":"查看订单","cardCode":"CARD_001","cardName":"perationCode":"H5","operationValue":"http:我的订单","tips":["可以点击【我的订单】【申请提货】按钮提货","可以点击【我的订单】【申请提货】按钮提货"],"titleContext":"您可点击下方按钮进入【我的订单】页面进行提货"},"chartId":"1434181,"isChart":0,"isContinuous":1,"isHit":1,"isLast":0,"question":"基价","questionId":"1452128","relatedQuestions":["基价"],"sessionId":"e455af0986d24c2daa2cdc50d62cec60","standardQuestion":"查基价","tips":["冷轧","热轧","中厚板","低合金"]}

Interface{}怎么转换成string?

类似下面的json,我如果只需要取 answerInfos[0],返回给前端怎么办?

"answerInfos": [{
		"question": "基价",
		"standardQuestion": "查基价",
		"questionId": "1452128",
		"isHit": 1,
		"relatedQuestions": [
			"基价"
		],
		"sessionId": "e455af0986d24c2daa2cdc50d62cec60",
		"answerCoded": "您要看哪个城市?&{R_001_001|ctg:中厚板|time:}",
		"answer": "您要看哪个城市?",
		"isChart": 0,
		"chartId": "1434187",
		"isContinuous": 1,
		"isLast": 0,
		"tips": [
			"冷轧",
			"热轧",
			"中厚板",
			"低合金"
		],
		"answerSource": "XIAO_I",
		"expandInfo": {
			"text": "查看更多",
			"url": "http://baidu.com"
		},
		"isCard": 1,
		"cardCode": "CARD_001",
		"cardInfo": {
			"buttonName": "查看订单",
			"cardCode": "CARD_001",
			"cardName": "打开订单",
			"loginCheck": 1,
			"operationCode": "H5",
			"operationValue": "http:我的订单",
			"tips": [
				"可以点击【我的订单】【申请提货】按钮提货",
				"可以点击【我的订单】【申请提货】按钮提货"
			],
			"titleContext": "您可点击下方按钮进入【我的订单】页面进行提货"
		}
	}],

答案:使用 simplejson.GetIndex() + json.Marshal() 即可


// 这是Interface{}类型
node := answerNode.GetIndex(index)

// row是interface{}类型,可以调用系统方法,再转换成一段json
data, err := json.Marshal(row)
if err == nil {
	fmt.Printf("answerInfos[%d]=%s", index, string(data))
}
参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

Go和分布式IM

请我喝一杯咖啡

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值