How can I unmarshall JSONp returned from a request?

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

How can I unmarshall JSONp returned from a request?

问题

我正在尝试使用美国农业部农贸市场目录API,通过邮政编码获取附近农贸市场的数据。我将响应的未解组的主体存储在以下结构中:

  1. type marketResponse struct {
  2. MapsLink string `json:"GoogleLink"`
  3. Address string `json:"Address"`
  4. Schedule string `json:"Schedule"`
  5. Products string `json:"Products"`
  6. }

使用以下代码:

  1. //TODO: location: "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/locSearch?lat=" + lat + "&lng=" + lng
  2. resp, err := http.Get("http://search.ams.usda.gov/farmersmarkets/v1/data.svc/zipSearch?zip=" + zipcode)
  3. if err != nil {
  4. log.Printf("无法搜索邮政编码 %s:%v", zipcode, err)
  5. }
  6. defer func() {
  7. if err := resp.Body.Close(); err != nil {
  8. log.Println(err)
  9. }
  10. }()
  11. body, err := ioutil.ReadAll(resp.Body)
  12. if err != nil {
  13. log.Println(err)
  14. }
  15. newMarket := &marketResponse{}
  16. if err := json.Unmarshal(body, newMarket); err != nil {
  17. log.Println(err)
  18. }
  19. log.Println("响应:" + newMarket.Address)

问题是,响应主体是JSONp格式,而我正在使用JSON解组。我该如何使用外部包或其他方法来解组JSONp格式的数据呢?

英文:

I'm attempting to use the USDA's Farmers Market Directory API to receive a data about where nearby farmer's markets are located, using a zip code. I store the unmarshalled body of the response in:

  1. type marketResponse struct {
  2. MapsLink string `json:"GoogleLink"`
  3. Address string `json:"Address"`
  4. Schedule string `json:"Schedule"`
  5. Products string `json:"Products"`
  6. }

Using the code:

  1. //TODO: location: "http://search.ams.usda.gov/farmersmarkets/v1/data.svc/locSearch?lat=" + lat + "&lng=" + lng
  2. resp, err := http.Get("http://search.ams.usda.gov/farmersmarkets/v1/data.svc/zipSearch?zip=" + zipcode)
  3. if err != nil {
  4. log.Printf("Could net search zipcode %s: %v", zipcode, err)
  5. }
  6. defer func() {
  7. if err := resp.Body.Close(); err != nil {
  8. log.Println(err)
  9. }
  10. }()
  11. body, err := ioutil.ReadAll(resp.Body)
  12. if err != nil {
  13. log.Println(err)
  14. }
  15. newMarket := &marketResponse{}
  16. if err := json.Unmarshal(body, newMarket); err != nil {
  17. log.Println(err)
  18. }
  19. log.Println("response: " + newMarket.Address)

The problem is, the response body is in JSONp, and I'm unmarshalling in JSON. How can I unmarshal in JSONp, using an external package, or not?

答案1

得分: 2

响应体是JSON格式的,根据响应的Content-Type:application/json; charset=utf-8头部字段。

问题在于你的marketResponse结构体与返回的JSON没有关联。使用JSON-to-Go,你的结构体应该如下所示:

  1. type MarketResponse struct {
  2. Results []Result `json:"results"`
  3. }
  4. type Result struct {
  5. ID string `json:"id"`
  6. Marketname string `json:"marketname"`
  7. }

目前不清楚你现有的marketResponse结构体在这里的作用,因为两个API端点都没有返回该结构体的数据。

另外,你应该处理(或返回)错误,而不仅仅是记录它们;记录错误仍然意味着你的函数会继续处理未处理的错误。当遇到空的响应体或JSON解析错误时,你的代码可能会发生恐慌。

英文:

The response body is JSON - as per the response's Content-Type:application/json; charset=utf-8 header.

The issue is that your marketResponse struct bears no relation to the JSON returned. Using JSON-to-Go, your struct should look like:

  1. type MarketResponse struct {
  2. Results []Result `json:"results"`
  3. }
  4. type Result struct {
  5. ID string `json:"id"`
  6. Marketname string `json:"marketname"`
  7. }

It's not clear where your existing marketResponse struct fits here, as neither API endpoint returns data with that structure.

PS: You should handle (or return) your errors and not just log them; logging them still means that your function continues with unhandled error. Your code might then panic when it encounters a nil response body or JSON unmarshalling error.

huangapple
  • 本文由 发表于 2016年4月24日 08:57:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/36818136.html
匿名

发表评论

匿名网友

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

确定