Parsing JSON in GoLang into struct

huangapple go评论76阅读模式
英文:

Parsing JSON in GoLang into struct

问题

所以,我在使用golang解析这个数据时遇到了一些问题:

{
    "gateways": [
        {
            "token": "my_token_here",
            "gateway_type": "test",
            "description": null,
            "payment_methods": [
                "credit_card",
                "sprel",
                "third_party_token",
                "bank_account",
                "apple_pay"
            ],
            "state": "retained",
            "created_at": "2016-03-12T18:52:37Z",
            "updated_at": "2016-03-12T18:52:37Z",
            "name": "Spreedly Test",
            "characteristics": [
                "purchase",
                "authorize",
                "capture",
                "credit",
                "general_credit",
                "void",
                "verify",
                "reference_purchase",
                "purchase_via_preauthorization",
                "offsite_purchase",
                "offsite_authorize",
                "3dsecure_purchase",
                "3dsecure_authorize",
                "store",
                "remove",
                "disburse",
                "reference_authorization"
            ],
            "credentials": [],
            "gateway_specific_fields": [],
            "redacted": false
        }
    ]
}

当我使用这个结构体时,我可以很容易地输出它。

type gateways struct {
    Gateways []struct {
        Characteristics       []string      `json:"characteristics"`
        CreatedAt             string        `json:"created_at"`
        Credentials           []interface{} `json:"credentials"`
        Description           interface{}   `json:"description"`
        GatewaySpecificFields []interface{} `json:"gateway_specific_fields"`
        GatewayType           string        `json:"gateway_type"`
        Name                  string        `json:"name"`
        PaymentMethods        []string      `json:"payment_methods"`
        Redacted              bool          `json:"redacted"`
        State                 string        `json:"state"`
        Token                 string        `json:"token"`
        UpdatedAt             string        `json:"updated_at"`
    } `json:"gateways"`
}

但是,一旦我将"Gateways []struct"分离成它自己的结构体,它就返回一个空数组...

完整的源代码如下:

type gateway struct {  
    Characteristics       []string      `json:"characteristics"`
    CreatedAt             string        `json:"created_at"`
    Credentials           []interface{} `json:"credentials"`
    Description           interface{}   `json:"description"`
    GatewaySpecificFields []interface{} `json:"gateway_specific_fields"`
    GatewayType           string        `json:"gateway_type"`
    Name                  string        `json:"name"`
    PaymentMethods        []string      `json:"payment_methods"`
    Redacted              bool          `json:"redacted"`
    State                 string        `json:"state"`
    Token                 string        `json:"token"`
    UpdatedAt             string        `json:"updated_at"`
}
type gateways struct {
    Gateways []gateway `json:"gateways"`
}

func ParseResponse() {
    var parsed gateways
    json.Unmarshal(json, &parsed)
}

希望对你有所帮助!

英文:

So, I'm having some trouble parsing this data in golang:

{
"gateways": [
    {
        "token": "my_token_here",
        "gateway_type": "test",
        "description": null,
        "payment_methods": [
            "credit_card",
            "sprel",
            "third_party_token",
            "bank_account",
            "apple_pay"
        ],
        "state": "retained",
        "created_at": "2016-03-12T18:52:37Z",
        "updated_at": "2016-03-12T18:52:37Z",
        "name": "Spreedly Test",
        "characteristics": [
            "purchase",
            "authorize",
            "capture",
            "credit",
            "general_credit",
            "void",
            "verify",
            "reference_purchase",
            "purchase_via_preauthorization",
            "offsite_purchase",
            "offsite_authorize",
            "3dsecure_purchase",
            "3dsecure_authorize",
            "store",
            "remove",
            "disburse",
            "reference_authorization"
        ],
        "credentials": [],
        "gateway_specific_fields": [],
        "redacted": false
    }
]

}

When using this struct I can get it to output pretty easily.

type gateways struct {
	Gateways []struct {
		Characteristics       []string      `json:"characteristics"`
		CreatedAt             string        `json:"created_at"`
		Credentials           []interface{} `json:"credentials"`
		Description           interface{}   `json:"description"`
		GatewaySpecificFields []interface{} `json:"gateway_specific_fields"`
		GatewayType           string        `json:"gateway_type"`
		Name                  string        `json:"name"`
		PaymentMethods        []string      `json:"payment_methods"`
		Redacted              bool          `json:"redacted"`
		State                 string        `json:"state"`
		Token                 string        `json:"token"`
		UpdatedAt             string        `json:"updated_at"`
	} `json:"gateways"` 
}

But as soon as I seperate the "Gateways []struct" into its own struct then it returns an empty array...

Full source.

type gateway struct {  
  Characteristics       []string      `json:"characteristics"`
  CreatedAt             string        `json:"created_at"`
  Credentials           []interface{} `json:"credentials"`
  Description           interface{}   `json:"description"`
  GatewaySpecificFields []interface{} `json:"gateway_specific_fields"`
  GatewayType           string        `json:"gateway_type"`
  Name                  string        `json:"name"`
  PaymentMethods        []string      `json:"payment_methods"`
  Redacted              bool          `json:"redacted"`
  State                 string        `json:"state"`
  Token                 string        `json:"token"`
  UpdatedAt             string        `json:"updated_at"`
}
type gateways struct {
  Gateways []gateway `json:"gateways"`
}

func ParseResponse() {
  var parsed gateways
  json.Unmarshal(json, &parsed)
}

答案1

得分: 1

你的ParseResponse函数存在问题,你在调用json.Unmarshal时将json作为第一个参数传递,但json是一个包名,这是不明确的。

你可以看到,只需更改ParseResponse函数,你的代码就可以正常工作。

package main

import (
	"encoding/json"
	"fmt"
)

type gateway struct {
	Characteristics       []string      `json:"characteristics"`
	CreatedAt             string        `json:"created_at"`
	Credentials           []interface{} `json:"credentials"`
	Description           interface{}   `json:"description"`
	GatewaySpecificFields []interface{} `json:"gateway_specific_fields"`
	GatewayType           string        `json:"gateway_type"`
	Name                  string        `json:"name"`
	PaymentMethods        []string      `json:"payment_methods"`
	Redacted              bool          `json:"redacted"`
	State                 string        `json:"state"`
	Token                 string        `json:"token"`
	UpdatedAt             string        `json:"updated_at"`
}

type gateways struct {
	Gateways []gateway `json:"gateways"`
}

func ParseResponse(js []byte) {
	var parsed gateways
	json.Unmarshal(js, &parsed)
	fmt.Println(parsed)
}

func main() {
	var js []byte = []byte(`{
"gateways": [
    {
        "token": "my_token_here",
        "gateway_type": "test",
        "description": null,
        "payment_methods": [
            "credit_card",
            "sprel",
            "third_party_token",
            "bank_account",
            "apple_pay"
        ],
        "state": "retained",
        "created_at": "2016-03-12T18:52:37Z",
        "updated_at": "2016-03-12T18:52:37Z",
        "name": "Spreedly Test",
        "characteristics": [
            "purchase",
            "authorize",
            "capture",
            "credit",
            "general_credit",
            "void",
            "verify",
            "reference_purchase",
            "purchase_via_preauthorization",
            "offsite_purchase",
            "offsite_authorize",
            "3dsecure_purchase",
            "3dsecure_authorize",
            "store",
            "remove",
            "disburse",
            "reference_authorization"
        ],
        "credentials": [],
        "gateway_specific_fields": [],
        "redacted": false
    }
]
}`)
	/*
		var parsed gateways
		e := json.Unmarshal(js, &parsed)
		if e != nil {
			fmt.Println(e.Error())
		} else {
			fmt.Println(parsed)
		}
	*/
	ParseResponse(js)
}

输出结果:

{[{[purchase authorize capture credit general_credit void verify reference_purchase purchase_via_preauthorization offsite_purchase offsite_authorize 3dsecure_purchase 3dsecure_authorize store remove disburse reference_authorization] 2016-03-12T18:52:37Z [] <nil> [] test Spreedly Test [credit_card sprel third_party_token bank_account apple_pay] false retained my_token_here 2016-03-12T18:52:37Z}]}
英文:

There's a problem with your ParseResponse function, you're calling json.Unmarshal passing as first parameter json, that's a packge name: that's ambiguous.

As you can see, your code works well changing the ParseResponse function.

package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
)
type gateway struct {
Characteristics       []string      `json:&quot;characteristics&quot;`
CreatedAt             string        `json:&quot;created_at&quot;`
Credentials           []interface{} `json:&quot;credentials&quot;`
Description           interface{}   `json:&quot;description&quot;`
GatewaySpecificFields []interface{} `json:&quot;gateway_specific_fields&quot;`
GatewayType           string        `json:&quot;gateway_type&quot;`
Name                  string        `json:&quot;name&quot;`
PaymentMethods        []string      `json:&quot;payment_methods&quot;`
Redacted              bool          `json:&quot;redacted&quot;`
State                 string        `json:&quot;state&quot;`
Token                 string        `json:&quot;token&quot;`
UpdatedAt             string        `json:&quot;updated_at&quot;`
}
type gateways struct {
Gateways []gateway `json:&quot;gateways&quot;`
}
func ParseResponse(js []byte) {
var parsed gateways
json.Unmarshal(js, &amp;parsed)
fmt.Println(parsed)
}
func main() {
var js []byte = []byte(`{
&quot;gateways&quot;: [
{
&quot;token&quot;: &quot;my_token_here&quot;,
&quot;gateway_type&quot;: &quot;test&quot;,
&quot;description&quot;: null,
&quot;payment_methods&quot;: [
&quot;credit_card&quot;,
&quot;sprel&quot;,
&quot;third_party_token&quot;,
&quot;bank_account&quot;,
&quot;apple_pay&quot;
],
&quot;state&quot;: &quot;retained&quot;,
&quot;created_at&quot;: &quot;2016-03-12T18:52:37Z&quot;,
&quot;updated_at&quot;: &quot;2016-03-12T18:52:37Z&quot;,
&quot;name&quot;: &quot;Spreedly Test&quot;,
&quot;characteristics&quot;: [
&quot;purchase&quot;,
&quot;authorize&quot;,
&quot;capture&quot;,
&quot;credit&quot;,
&quot;general_credit&quot;,
&quot;void&quot;,
&quot;verify&quot;,
&quot;reference_purchase&quot;,
&quot;purchase_via_preauthorization&quot;,
&quot;offsite_purchase&quot;,
&quot;offsite_authorize&quot;,
&quot;3dsecure_purchase&quot;,
&quot;3dsecure_authorize&quot;,
&quot;store&quot;,
&quot;remove&quot;,
&quot;disburse&quot;,
&quot;reference_authorization&quot;
],
&quot;credentials&quot;: [],
&quot;gateway_specific_fields&quot;: [],
&quot;redacted&quot;: false
}
]
}`)
/*
var parsed gateways
e := json.Unmarshal(js, &amp;parsed)
if e != nil {
fmt.Println(e.Error())
} else {
fmt.Println(parsed)
}
*/
ParseResponse(js)
}

Outputs:

{[{[purchase authorize capture credit general_credit void verify reference_purchase purchase_via_preauthorization offsite_purchase offsite_authorize 3dsecure_purchase 3dsecure_authorize store remove disburse reference_authorization] 2016-03-12T18:52:37Z [] &lt;nil&gt; [] test Spreedly Test [credit_card sprel third_party_token bank_account apple_pay] false retained my_token_here 2016-03-12T18:52:37Z}]}

答案2

得分: 0

请看 http://play.golang.org/p/3xJHBmhuei - 将数据解组成你的第二个 gateways 定义是成功的,所以你可能只是漏掉了一些小细节。

检查一下 json.Unmarshal 调用是否返回了错误。

另外,如果你能够成功地将数据解组成第一个版本的 gateways,那么问题可能不在这里,但是你提供的 JSON 字符串缺少一个闭合的 "}" 括号。

英文:

Take a look at http://play.golang.org/p/3xJHBmhuei - unmarshalling into your second definition of gateways completes successfully, so it must be something little that you're missing.

Check if the json.Unmarshal call returns an error.

P.S. It probably isn't the problem if you're unmarshalling successfully into the first version of gateways, but the JSON string that you've given above is missing a closing "}" bracket.

huangapple
  • 本文由 发表于 2016年3月13日 20:42:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/35970395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定