10

Goについて質問してencoding/jsonいますが、JSONブロブを任意の言語のオブジェクトにマップする他の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"
 }
}

これに対処する慣用的な方法はありますか?2つの完全に異なるスキーマに準拠する可能性のある応答ですか?

通常、私はマップ/リストを使用してJSONを扱います。私はそれが囲碁で可能であることを知っています。にマーシャリングを解除してからmap[string]interface{}、マップに"error"キーがあるかどうかを確認できます。しかし、それなら私は再び適切なものにデコードする必要structがあると思います。(私が間違っている?)

私はこのようなことをしています。応答の種類ごとに1つのタイプがあります。

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
    }
}

しかし、それはちょっと醜いようです。これにどのようにアプローチすればよいですか?

4

4 に答える 4

6

json応答のフィールドは互いに異なるため、すべてのフィールドを結合して1つの構造体を作成できます。jsonデコーダーは、json文字列に存在しないフィールドを無視します。フィールドの存在をテストして、返される応答のタイプを知ることができます。

于 2012-08-24T06:22:35.437 に答える
6

私もこれについて混乱し、もう一度デコードする必要があると思いました。しかし、あなたはしません。interface{}データを適切な構造に型キャストする必要があります。

たとえば、jsonパッケージが値をジェネリックに入れている場合は、でinterface{}型キャストできます。ErrorTypeerror := val.(ErrorType)

値のタイプに基づいて解析している場合はfoo.(type)、ステートメントで「正しいことを行う」ために使用できます。switch

私は今週Goを学んでいるだけなので、これは最も美しいコードではありませんが、geodnsJSON構成の解析にいくつかの例があります。

于 2012-08-26T08:02:26.403 に答える
5

Go-SimpleJSONを試しましたか?これで問題が解決するかもしれません。

于 2012-08-24T07:37:17.180 に答える
3
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
}
于 2012-08-24T10:48:00.233 に答える