1

次の形式で JSON を返す API にアクセスしています。

[{"UniqueID":1234, "DocID":5678}, {"UniqueID":5678, "DocID":9101112}]

この API は Go で記述されており、そのサンプル出力はブラウザーでの戻り値の表示方法です。content-type ヘッダーは application/json です

これを取得して非整列化する次のコードがあります。

    type UniqueIDDocID struct{
        UniqueID int64 `json: "UniqueID"`
        DocID int64 `json: "DocID"`
    }
    type UniqueIDDocIDCollection struct{
        FullList []UniqueIDDocID
    }

    func retrieveUniqueIDByPublication(nodeid int64, publication string){
        // call the API
        //hgr := new(retrieval.HttpGetRetrieval)
// endpoint is defined here - I have removed for privacy reasons
        fmt.Println(endpoint) // the url which I know works
        /*response, err := hgr.RequestResponse(endpoint)
            if err != nil {
                l4g.Warn("Could not retrieve the endpoint %s. Error: ", endpoint, err)
                return
            }
            defer hgr.CloseResponse(response)
            queryResult := hgr.ReadResponse(response)*/
            client := new(http.Client)
            request, err := http.NewRequest("GET", endpoint, nil)
            if err != nil {
                l4g.Warn("Could not retrieve the endpoint %s. Error: %v", endpoint, err)
                return  
            }
            request.Header.Set("Content-Type", "applicaiton/json")
            response, err := client.Do(request)
            if err != nil {
                l4g.Warn("Could not retrieve the endpoint %s. Error: %v", endpoint, err)
                return  
            }
            defer response.Body.Close()
            var reader io.ReadCloser
            reader = response.Body
            defer reader.Close()
            queryResult, readErr := ioutil.ReadAll(reader)
            if err != nil {
                l4g.Warn("Could not retrieve the endpoint %s. Error: %v", endpoint, readErr)
                return  
            }
            if queryResult == nil {
                l4g.Warn("Nothing returned %s.", endpoint)
                return
            }


            var details UniqueIDDocIDCollection
        // process return
            if err:=json.Unmarshal(queryResult, &details); err != nil{
                l4g.Warn("Failed to unmarshall return %v from %s", queryResult, endpoint)
                return
            }
            writeUniqueIDFile(details)
    }

「アンマーシャルに失敗しました」というメッセージが表示され、ログの詳細には次のようなものが表示されます。

[91 123 34 85 110 105 113 117 101 73 68 34 58 34 56 51     57 51 50 53 56 54 34 44 34 68 111 99 73 68 34 58 52 49 50 49 54 57 49 57 125 44 123 34 85 110 105 113 117 101]

代表的なサンプルとして。

この非整列化ステップで何が間違っていますか?

私の望む出力は、UniqueIDDocIDCollection structu に UniqueIDDocID タイプのアイテムを含むスライスがあり、そこから UniqueID を取得して行区切りファイルに書き込むことができるということです。

私はグーグルでいろいろと試してみましたが、毎回これが得られます。

ソース JSON についても何か提案があれば、API で変更できるかもしれないので、それらを共有してください。

事前に助けてくれてありがとうネイサン

4

1 に答える 1

1

エラー データは [] バイト スライスです。それを %s ( ) に Printf するかfmt.Printf("foo: %s\n", foo)、現在ラップしている場所であれば、より便利なものが得られる可能性がありますstring(foo)

アンマーシャルのより簡単な例を作成しましたが、うまくいくようです。結局、問題は入力データにあると思いますか?

package main

import (
    "encoding/json"
    "log"
)

type UniqueIDDocID struct {
    UniqueID int64 `json: "UniqueID"`
    DocID    int64 `json: "DocID"`
}
type UniqueIDDocIDCollection struct {
    FullList []UniqueIDDocID
}

const INPUT = `[{"UniqueID":1234, "DocID":5678}, {"UniqueID":5678, "DocID":9101112}]`

func main() {

    coll := new(UniqueIDDocIDCollection)

    err := json.Unmarshal([]byte(INPUT), &coll.FullList)

    if err != nil {
        log.Printf("Could not unmarshall %s: %s", INPUT, err)
    }

    log.Printf("Now have data: %#v\n", coll)

}

出力 ( play.golang で試してください)

Now have data: &main.UniqueIDDocIDCollection{FullList:[]main.UniqueIDDocID{main.UniqueIDDocID{UniqueID:1234, DocID:5678}, main.UniqueIDDocID{UniqueID:5678, DocID:9101112}}}

「アンマーシャリングに失敗しました」というエラー メッセージを に変更すること%vから始めます。%s期待するデータがない可能性があります。json.Unmarshall から返されたエラーも含める必要があります。何が問題なのかがわかります。:-)

于 2013-07-23T17:02:00.587 に答える