简体   繁体   English

如何在Go中通过HTTP解组JSON

[英]How to Unmarshall JSON Retrived over http in Go

I am accessing an API that returns JSON in the form: 我正在访问以以下形式返回JSON的API:

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

this API was written in Go and that sample output is how the return is displayed in a browser. 该API是用Go编写的,该示例输出是返回值在浏览器中的显示方式。 the content-type header is application/json 内容类型标头是application / json

I have the following code to retrieve and unmarshal this: 我有以下代码来检索和解组该代码:

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

I am getting the "Failed to Unmarshall" message and the details in the log shows things like: 我收到“无法解组”消息,日志中的详细信息显示如下内容:

[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]

As a representative sample. 作为代表性样品。

What am I doing wrong in this unmarshall step? 在此解组步骤中,我在做什么错?

My desired output is that the UniqueIDDocIDCollection structu has a slice on it that contains items of type UniqueIDDocID that I can then take the UniqueID from and write it to a line delimited file. 我希望得到的输出是,UniqueIDDocIDCollection结构上有一个切片,其中包含类型为UniqueIDDocID的项目,然后我可以从中获取UniqueID并将其写入行分隔文件。

I have been Googling around and have tried a number of things but each time this is what I get. 我一直在谷歌搜索,并尝试了许多方法,但是每次这都是我得到的。

If you have any suggestions about the source JSON too then share those as I may be able to make the changes in the API. 如果您也对源JSON有任何建议,请与我分享,因为我可能可以在API中进行更改。

Thanks for the help in advance Nathan 感谢您提前的帮助内森

The error data is a []byte slice; 错误数据是[] byte切片; you will likely get something more useful if you Printf it to a %s ( fmt.Printf("foo: %s\\n", foo) ) or wherever you have it now wrap it in string(foo) . 如果将Printf fmt.Printf("foo: %s\\n", foo)到%s( fmt.Printf("foo: %s\\n", foo) )或现在将其包装在string(foo)则可能会得到一些更有用的东西。

I made a simpler example of your Unmarshall, and it seems to work fine. 我为您的Unmarshall制作了一个简单的示例,它似乎运行良好。 I suspect the problem is with the input data after all? 我怀疑问题毕竟出在输入数据上吗?

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)

}

Outputs ( try it on play.golang ) 输出( 在play.golang上尝试

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

Start by changing %v to %s in the "failed to unmarshall" error message; 首先在“无法解组”错误消息中将%v更改为%s maybe you don't have the data you are expecting. 也许您没有期望的数据。 You should also include the error returned from json.Unmarshall, it might tell you what's going wrong. 您还应该包含从json.Unmarshall返回的错误,它可能会告诉您出了什么问题。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM