#json #go
#json #Вперед
Вопрос:
Я пытаюсь декодировать некоторый json в Go, но некоторые поля не декодируются. Смотрите код, запущенный в браузере, здесь:
Что я делаю не так?
Мне нужны только записи MX, поэтому я не определял другие поля. Насколько я понимаю из godoc, вам не нужно определять поля, которые вы не используете / не нужны.
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
import "encoding/json"
func main() {
body := `
{"response": {
"status": "SUCCESS",
"data": {
"mxRecords": [
{
"value": "us2.mx3.mailhostbox.com.",
"ttl": 1,
"priority": 100,
"hostName": "@"
},
{
"value": "us2.mx1.mailhostbox.com.",
"ttl": 1,
"priority": 100,
"hostName": "@"
},
{
"value": "us2.mx2.mailhostbox.com.",
"ttl": 1,
"priority": 100,
"hostName": "@"
}
],
"cnameRecords": [
{
"aliasHost": "pop.a.co.uk.",
"canonicalHost": "us2.pop.mailhostbox.com."
},
{
"aliasHost": "webmail.a.co.uk.",
"canonicalHost": "us2.webmail.mailhostbox.com."
},
{
"aliasHost": "smtp.a.co.uk.",
"canonicalHost": "us2.smtp.mailhostbox.com."
},
{
"aliasHost": "imap.a.co.uk.",
"canonicalHost": "us2.imap.mailhostbox.com."
}
],
"dkimTxtRecord": {
"domainname": "20a19._domainkey.a.co.uk",
"value": ""v=DKIM1; g=*; k=rsa; p=DkfbhO8Oyy0E1WyUWwIDAQAB"",
"ttl": 1
},
"spfTxtRecord": {
"domainname": "a.co.uk",
"value": ""v=spf1 redirect=_spf.mailhostbox.com"",
"ttl": 1
},
"loginUrl": "us2.cp.mailhostbox.com"
}
}}`
type MxRecords struct {
value string
ttl int
priority int
hostName string
}
type Data struct {
mxRecords []MxRecords
}
type Response struct {
Status string `json:"status"`
Data Data `json:"data"`
}
type apiR struct {
Response Response
}
var r apiR
err := json.Unmarshal([]byte(body), amp;r)
if err != nil {
fmt.Printf("err was %v", err)
}
fmt.Printf("decoded is %v", r)
}
Ответ №1:
Согласно документу go о json.Unmarshal, вы можете декодировать только в направлении экспортированных полей, основная причина заключается в том, что внешние пакеты (такие как encoding/json
) не могут получить доступ к неэкспортированным полям.
Если ваш json не соответствует соглашению go для имен, вы можете использовать json
тег в своих полях, чтобы изменить соответствие между ключом json и полем struct .
Exemple:
package main
import (
"fmt"
"encoding/json"
)
type T struct {
Foo string `json:"foo"`
priv string `json:"priv"`
}
func main() {
text := []byte(`{"foo":"bar", "priv":"nothing"}`)
var t T
err := json.Unmarshal(text, amp;t)
if err != nil {
panic(err)
}
fmt.Println(t.Foo) // prints "bar"
fmt.Println(t.priv) // prints "", priv is not exported
}
Комментарии:
1. В чем значение
json:"foo"
in struct?2. @DevendraBhat в теге указано, каким будет имя сериализованного поля в json. Без тега он будет сериализован с заглавной буквы
{"Foo": "bar"}
3. добавлен пример с неэкспортируемым полем
Ответ №2:
Вы должны вводить поля структуры в верхнем регистре:
type MxRecords struct {
Value string `json:"value"`
Ttl int `json:"ttl"`
Priority int `json:"priority"`
HostName string `json:"hostName"`
}
type Data struct {
MxRecords []MxRecords `json:"mxRecords"`
}
Ответ №3:
encoding/json
Пакет может декодироваться только в экспортированные поля структуры. Ваш Data.mxRecords
член не экспортируется, поэтому он игнорируется при декодировании. Если вы переименуете его, чтобы использовать заглавную букву, пакет JSON заметит это.
Вам нужно будет сделать то же самое для всех членов вашего MxRecords
типа.