2016-06-21 34 views
0

我想通過我的IP地址使用http://ip-api.com/ api來獲取經度和緯度。當我從瀏覽器或curl訪問http://ip-api.com/json時,它會在json中返回正確的信息。但是當我嘗試從我的程序中使用API​​時,API響應有一個空的主體(或者看起來好像)。試圖查詢一個API,但API響應是空的

我想在這個應用程序中做到這一點。該Ip_response_success結構是根據這裏的API文檔http://ip-api.com/docs/api:json

type Ip_response_success struct { 
    as   string 
    city  string 
    country  string 
    countryCode string 
    isp   string 
    lat   string 
    lon   string 
    org   string 
    query  string 
    region  string 
    regionName string 
    status  string 
    timezone string 
    zip   string 
} 

func Query(url string) (Ip_response_success, error) { 
    resp, err := http.Get(url) 
    if err != nil { 
     return Ip_response_success{}, err 
    } 
    fmt.Printf("%#v\n", resp) 

    var ip_response Ip_response_success 
    defer resp.Body.Close() 
    err = json.NewDecoder(resp.Body).Decode(&ip_response) 
    if err != nil { 
     return Ip_response_success{}, err 
    } 
    body, err := ioutil.ReadAll(resp.Body) 
    fmt.Printf("%#v\n", string(body)) 
    return ip_response, nil 
} 

func main() { 
    ip, err := Query("http://ip-api.com/json") 
    if err != nil { 
     fmt.Printf("%#v\n", err) 
    } 
} 

但最奇特的地方響應的正文爲空做。它在響應中提供了200個狀態碼,所以我假設在API調用中沒有錯誤。該API沒有提及任何認證要求或用戶代理要求,事實上,當我通過瀏覽器對其進行卷曲或訪問時,似乎不需要任何特別的東西。有沒有什麼我在做我的程序錯誤或我使用API​​錯誤?

我嘗試在代碼內打印響應,但resp.body只是空白。來自http.Response結構的打印樣本響應:

&http.Response{Status:"200 OK", StatusCode:200, Proto:"HTTP/1.1", ProtoMajor:1, 
ProtoMinor:1, Header:http.Header{"Access-Control-Allow-Origin":[]string{"*"}, 
"Content-Type":[]string{"application/json; charset=utf-8"}, "Date": 
[]string{"Tue, 21 Jun 2016 06:46:57 GMT"}, "Content-Length":[]string{"340"}}, 
Body:(*http.bodyEOFSignal)(0xc820010640), ContentLength:340, TransferEncoding: 
[]string(nil), Close:false, Trailer:http.Header(nil), Request:(*http.Request) 
(0xc8200c6000), TLS:(*tls.ConnectionState)(nil)} 

任何幫助將不勝感激!

回答

2

首先,你必須閱讀的身體,然後分析它:

body, err := ioutil.ReadAll(resp.Body) 
err = json.NewDecoder(body).Decode(&ip_response) 
if err != nil { 
    return Ip_response_success{}, err 
} 

另外,在去了,JSON解碼器必須能夠訪問到結構的領域。這意味着他們必須暴露在你的包裝之外。

這意味着你使用JSON批註指定映射:

type Ip_response_success struct { 
    As   string `json: "as"` 
    City  string `json: "city"` 
    Country  string `json: "country"` 
    CountryCode string `json: "countryCode"` 
    Isp   string `json: "isp"` 
    Lat   float64 `json: "lat"` 
    Lon   float64 `json: "lon"` 
    Org   string `json: "org"` 
    Query  string `json: "query"` 
    Region  string `json: "region"` 
    RegionName string `json: "regionName"` 
    Status  string `json: "status"` 
    Timezone string `json: "timezone"` 
    Zip   string `json: "zip"` 
} 

還請注意,我改變了經度/緯度類型根據服務器發送

+0

感謝數據float64。我會嘗試這兩件事。 –

+0

爲什麼http://stackoverflow.com/a/31129967建議跳過'ioutil.ReadAll'並立即使用'Decode'? –

+0

好吧,我修改了結構後有大寫字段。在解析它之前,我不必閱讀主體。我保持原樣。現在它工作了!謝謝! –