我正在连接到一个提供相当大的json有效负载的API。我需要向根对象添加键和值。一旦从包“ net / http”中执行ioutil.Readall
,JSON就是一个字节数组。
我的目标是仅添加到结构中并继续前进。例如,以下内容与我正在执行的操作非常相似:https://tutorialedge.net/golang/consuming-restful-api-with-go/
那么如何简单地将另一个元素(键:值)添加到JSON结构中?
答案 0 :(得分:5)
如果您要做的只是向根对象添加键和值并生成新的JSON,并且您不关心将数据存储在结构中,则可以将其解编为map[string]interface{}
,然后添加值,然后再次编组:
var m map[string]interface{}
err := json.Unmarshal(data, &m)
m["new_key"] = newValue
newData, err := json.Marshal(m)
(我不检查错误,但是您应该这样做。)查看https://golang.org/pkg/encoding/json/,以获取有关如何在Go中处理JSON的更多信息。
答案 1 :(得分:2)
由于您有字节数据,因此需要使用json.Marshal对其进行解析并将结果存储在具有json结构的变量中。
然后,要添加新的键值对,可以使用键及其数据类型定义新的struct
var variable type1
// Unmarshal the byte data in a variable
json.Unmarshall(data, &variable)
// to add a new key value you can define a new type
type type2 struct {
type1
key type
}
// and you can add
variable2 := type2{variable, newValueToAdd}
答案 2 :(得分:2)
虽然反序列化和重新序列化是更“正确”的方法,但是仅在根上添加一个值可能会过大,这可以通过简单的字符串操作(确实是字节片操作)来完成,但是语义相似,并且可以说是有道理的更容易):
data := []byte(`{"foo": 1, "bar": true}`)
ins := []byte(`, "baz": "hello"`) // Note the leading comma.
closingBraceIdx := bytes.LastIndexByte(data, '}')
data = append(data[:closingBraceIdx], ins...)
data = append(data, '}')
这更容易出错,因为它完全不了解JSON语法,但是对于大多数情况和大型JSON文档而言,它足够安全,比解析,插入和重新序列化更为有效。
答案 3 :(得分:2)
以下是如何以有效的方式执行此操作,同时保留原始 JSON 中的键顺序。这个想法是使用 json.RawMessage
// original JSON
bytes := []byte(`{"name": "Adele", "age": 24}`)
// let's try to add the kv pair "country": "USA" to it
type Person struct {
Bio json.RawMessage `json:"bio"`
Country string `json:"country"`
}
p := Person{
Bio: json.RawMessage(bytes),
Country: "USA",
}
// ignoring error for brevity
modifiedBytes, _ := json.Marshal(p)
fmt.Println(string(modifiedBytes))
输出:
{"bio":{"name":"Adele","age":24},"country":"USA"}
您可以看到保留了原始 JSON 的顺序,如果您将 JSON 编组为 map[string]interface{}
,则不会出现这种情况。当您处理巨大的 JSON 时,这也更有效,因为不涉及反射。
答案 4 :(得分:1)
如果要将json字节的键值添加到新的json对象,则可以使用json.RawMessage。
type Res struct {
Data interface{}
Message string
}
var row json.RawMessage
row = []byte(`{"Name":"xxx","Sex":1}`)
res := Res{Data:row,Message:"user"}
resBytes ,err := json.Marshal(res)
println(string(resBytes))
//print result:"Data":{"Name":"xxx","Sex":1},"Message":"user"}