英文:
Go unmarshal JSON with unknown field name but known struct
问题
我从traefik tls中获取了一个acme.json文件,其中traefik存储了SSL/TLS证书的信息。
现在我想要使用golang将acme.json反序列化到我的go结构体"Traefik"中。但是我不知道如何处理动态/未知的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的Go结构体
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"` // 在这里写什么?它应该适用于certificateresolver1和certificateresolver2
}
英文:
I retrieve a acme.json from traefik tls where traefik stores ssl/tls certificate information.
Now I want to unmarshal with golang the acme.json into my go struct "Traefik". But I don't know how to handle dynamic/unknown json field names because certificateresolver1
and certificateresolver2
are names I don't know at compile time. These names should be dynamic configured in go.
I know the structure of the json (it is always the same) but not know the field name of the certificateresolver.
Does anyone know the best way to do this?
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"
}
]
}
}
Go struct for 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
}
答案1
得分: 3
我认为这样的代码可以帮到你:
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)
}
完整的示例可以在这里找到。
英文:
I think something like this will help you:
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"`
}
So you could work with this data in this way:
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)
}
Full example here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论