在Go中解码可变模式JSON

我想问有关Go的问题encoding/json,但我想它也适用于将JSON Blob映射到任何语言的对象的任何其他JSON库。

这是一个例子。如果您想使用goo.gl URL Shortener API来缩短URL ,则可以返回一个成功的响应:

{

 "kind": "urlshortener#url",

 "id": "http://goo.gl/fbsS",

 "longUrl": "http://www.google.com/"

}

或错误响应:


{

 "error": {

  "errors": [

   {

    "domain": "global",

    "reason": "required",

    "message": "Required",

    "locationType": "parameter",

    "location": "resource.longUrl"

   }

  ],

  "code": 400,

  "message": "Required"

 }

}

有没有一种惯用的方式来处理这个问题-可能会遵循两个完全不同的模式的响应?


通常,我使用地图/列表处理JSON;我知道Go中有可能。我可以解组到a map[string]interface{},然后检查地图是否已"error"作为关键。但是,我想我必须再次将其解码为适当的struct。(我错了吗?)


我正在做这样的事情。对于每种响应,我都有一种类型:


type successResponse struct {

    Kind string

    Id string

    LongUrl string

}


type errorResponse struct {

    Error struct {

        Errors []struct {

            Domain string

            Reason string

            Message string

            LocationType string

            Location string

        }

        Code int

        Message string

    }

}

解码看起来像这样:


s := new(successResponse)

err := json.Unmarshal(blob, s)

if err == nil {

    // handle success

} else {

    e := new(errorResponse)

    err = json.Unmarshal(blob, e)

    if err == nil {

        // handle error response

    } else {

        // handle actual error

    }

}

但这看起来很难看。我应该如何处理?


肥皂起泡泡
浏览 246回答 3
3回答

守候你守候我

由于json响应中的字段彼此不同,因此您只需创建一个具有所有字段并集的结构即可。json解码器将忽略json字符串中不存在的字段,并且您可以测试这些字段的存在,以了解要返回的响应类型。

胡说叔叔

我对此也感到困惑,并以为我必须再次对其进行解码。不过你没有。您只需要将interface {}数据类型转换为适当的结构。例如,如果JSON包已经把值转换成通用的interface{},可以强制转换成ErrorType用error := val.(ErrorType)。如果要根据值的类型进行解析,则可以foo.(type)在switch语句中使用“做正确的事”。我本周只学习Go,所以它不是最漂亮的代码,但是geodns JSON配置解析中有一些示例。

慕田峪7331174

type Response struct {    Kind    string    Id      string    LongUrl string    Error   struct {        Errors []struct {            Domain       string            Reason       string            Message      string            LocationType string            Location     string        }        Code    int        Message string    }}s := Response{}if err := json.Unmarshal(blob, &s); err == nil {    if s.Error == nil {        // success    } else {        // error    }} else {    // something went wrong}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go