解组 JSON 字段名称未知但结构已知
Go unmarshal JSON with unknown field name but known struct
我从 traefik tls 中检索了一个 acme.json,其中 traefik 存储 ssl/tls 证书信息。
现在我想用 golang 将 acme.json 解组到我的 go 结构“Traefik”中。但是我不知道如何处理 dynamic/unknown json 字段名称,因为 certificateresolver1
和 certificateresolver2
是我在编译时不知道的名称。这些名称应该是在 go 中动态配置的。
我知道 json 的结构(它总是相同的)但不知道 certificateresolver 的字段名称。
有谁知道最好的方法吗?
Traefik acme.json
{
"certificateresolver1": {
"Account": {
"Email": "email@example.com",
"Registration": {
"body": {
"status": "valid",
"contact": [
"mailto:email@example.com"
]
},
"uri": "https://acme-v02.api.letsencrypt.org/acme/acct/124448363"
},
"PrivateKey": "PRIVATEKEY",
"KeyType": "4096"
},
"Certificates": [
{
"domain": {
"main": "example.com",
"sans": [
"test.example.com"
]
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
},
{
"domain": {
"main": "example.org"
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
}
]
},
"certificateresolver2": {
"Account": {
"Email": "email@example.com",
"Registration": {
"body": {
"status": "valid",
"contact": [
"mailto:email@example.com"
]
},
"uri": "https://acme-v02.api.letsencrypt.org/acme/acct/126945414"
},
"PrivateKey": "PRIVATEKEY",
"KeyType": "4096"
},
"Certificates": [
{
"domain": {
"main": "example.net"
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
}
]
}
}
为 acme.json
构建结构
type Traefik struct {
Provider []struct {
Account struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
Contact []string `json:"contact"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
PrivateKey string `json:"PrivateKey"`
KeyType string `json:"KeyType"`
} `json:"Account"`
Certificates []struct {
Domain struct {
Main string `json:"main"`
Sans []string `json:"sans"`
} `json:"domain"`
Certificate string `json:"certificate"`
Key string `json:"key"`
Store string `json:"Store"`
} `json:"Certificates"`
} `json:"certificateresolver"` <-- What to write there? It should fit for certificateresolver1 and certificateresolver2
}
我认为这样的事情会对你有所帮助:
type ProviderMdl map[string]Provider
type Provider struct {
Account struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
Contact []string `json:"contact"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
PrivateKey string `json:"PrivateKey"`
KeyType string `json:"KeyType"`
} `json:"Account"`
Certificates []struct {
Domain struct {
Main string `json:"main"`
Sans []string `json:"sans"`
} `json:"domain"`
Certificate string `json:"certificate"`
Key string `json:"key"`
Store string `json:"Store"`
} `json:"Certificates"`
}
所以你可以这样处理这些数据:
bres := new(ProviderMdl)
if err := json.Unmarshal(data, bres); err != nil {
panic(err)
}
// fmt.Printf("%+v - \n", bres)
for key, value := range *bres {
fmt.Printf("%v - %v\n", key, value)
}
完整示例here
我从 traefik tls 中检索了一个 acme.json,其中 traefik 存储 ssl/tls 证书信息。
现在我想用 golang 将 acme.json 解组到我的 go 结构“Traefik”中。但是我不知道如何处理 dynamic/unknown json 字段名称,因为 certificateresolver1
和 certificateresolver2
是我在编译时不知道的名称。这些名称应该是在 go 中动态配置的。
我知道 json 的结构(它总是相同的)但不知道 certificateresolver 的字段名称。
有谁知道最好的方法吗?
Traefik acme.json
{
"certificateresolver1": {
"Account": {
"Email": "email@example.com",
"Registration": {
"body": {
"status": "valid",
"contact": [
"mailto:email@example.com"
]
},
"uri": "https://acme-v02.api.letsencrypt.org/acme/acct/124448363"
},
"PrivateKey": "PRIVATEKEY",
"KeyType": "4096"
},
"Certificates": [
{
"domain": {
"main": "example.com",
"sans": [
"test.example.com"
]
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
},
{
"domain": {
"main": "example.org"
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
}
]
},
"certificateresolver2": {
"Account": {
"Email": "email@example.com",
"Registration": {
"body": {
"status": "valid",
"contact": [
"mailto:email@example.com"
]
},
"uri": "https://acme-v02.api.letsencrypt.org/acme/acct/126945414"
},
"PrivateKey": "PRIVATEKEY",
"KeyType": "4096"
},
"Certificates": [
{
"domain": {
"main": "example.net"
},
"certificate": "CERTIFICATE",
"key": "KEY",
"Store": "default"
}
]
}
}
为 acme.json
构建结构type Traefik struct {
Provider []struct {
Account struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
Contact []string `json:"contact"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
PrivateKey string `json:"PrivateKey"`
KeyType string `json:"KeyType"`
} `json:"Account"`
Certificates []struct {
Domain struct {
Main string `json:"main"`
Sans []string `json:"sans"`
} `json:"domain"`
Certificate string `json:"certificate"`
Key string `json:"key"`
Store string `json:"Store"`
} `json:"Certificates"`
} `json:"certificateresolver"` <-- What to write there? It should fit for certificateresolver1 and certificateresolver2
}
我认为这样的事情会对你有所帮助:
type ProviderMdl map[string]Provider
type Provider struct {
Account struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
Contact []string `json:"contact"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
PrivateKey string `json:"PrivateKey"`
KeyType string `json:"KeyType"`
} `json:"Account"`
Certificates []struct {
Domain struct {
Main string `json:"main"`
Sans []string `json:"sans"`
} `json:"domain"`
Certificate string `json:"certificate"`
Key string `json:"key"`
Store string `json:"Store"`
} `json:"Certificates"`
}
所以你可以这样处理这些数据:
bres := new(ProviderMdl)
if err := json.Unmarshal(data, bres); err != nil {
panic(err)
}
// fmt.Printf("%+v - \n", bres)
for key, value := range *bres {
fmt.Printf("%v - %v\n", key, value)
}
完整示例here