2015-06-24 67 views
2

我是Go的新手。 我一直在嘗試使用their API從Flickr獲取照片,但我正面臨解析JSON響應的問題。轉到JSON解析

我一直在Go中編寫服務器來處理Web服務調用。 我的輸出看起來是這樣的:

{ 
    "photos": { 
     "page": 1, 
     "pages": 3583, 
     "perpage": 100, 
     "total": "358260", 
     "photo": [ 
      { 
       "id": "18929318980", 
       "owner": "[email protected]", 
       "secret": "505225f721", 
       "server": "469", 
       "farm": 1, 
       "title": "❤️ Puppy Dog Eyes❤️ #Cute #baby #havanese #puppy #love #petsofinstagram #akC#aplacetolovedogs #all_little_puppies #americankennelclub #beautiful #bestanimal #puppies #cutestdogever #dog #doglife #doglover #dogoftheday", 
       "ispublic": 1, 
       "isfriend": 0, 
       "isfamily": 0 
      }, 
      { 
       "id": "18930020399", 
       "owner": "[email protected]", 
       "secret": "449f493ebc", 
       "server": "496", 
       "farm": 1, 
       "title": "Titt tei hvem er du for en liten tass Osvald og King #cat#kitten #bordercollie #puppy#dog", 
       "ispublic": 1, 
       "isfriend": 0, 
       "isfamily": 0 
      }, 
      { 
       "id": "18929979989", 
       "owner": "[email protected]", 
       "secret": "7da344edcb", 
       "server": "498", 
       "farm": 1, 
       "title": "Shame, Shame", 
       "ispublic": 1, 
       "isfriend": 0, 
       "isfamily": 0 
      } 
      ] 
    }, 
    "stat": "ok" 
} 

當我試圖運行的代碼它顯示:

package main 

import(
     "os" 
     "fmt" 
     "log" 
     "net/http" 
     "io/ioutil" 
     "encoding/json" 
     "github.com/gorilla/mux" 

) 
type Result struct { 
     Photos struct { 
     Page int `json: "page"` 
     Pages int `json: "pages"` 
     PerPage int `json: "perpage"` 
     Total int `json: "total"` 
     Photo []struct { 
      Id int `json: "id"` 
      Owner string `json: "owner"` 
      Secret string `json: "secret"` 
      Server int `json: "server"` 
      Farm int `json: "farm"` 
      Title string `json: "title"` 
      IsPublic int `json: "ispublic"` 
      IsFriend int `json: "isfriend"` 
      IsFamily int `json: "isfamily` 
      } `json: "photo"` 
    } `json: "photos"` 
    Stat string `json: "stat"` 
} 

func main() { 

    router := mux.NewRouter().StrictSlash(true); 
    router.HandleFunc("/Index", Index) 
    log.Fatal(http.ListenAndServe(":8084", router)) 
} 

func Index(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Content-Type", "application/json"); 
    url := "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=6b54d86b4e09671ef6a2a8c02b7a3537&text=cute+puppies&format=json&nojsoncallback=1" 
    res, err := http.Get(url) 
    if err != nil{ 
     fmt.Printf("%s", err) 
     os.Exit(1) 
    } 
    body, err := ioutil.ReadAll(res.Body) 
    if err != nil{ 
     fmt.Printf("%s", err) 
     os.Exit(1) 
    } 

    jsonData := &Result{} 
    err = json.Unmarshal([]byte(body), &jsonData) 
    for i := 0;i < len(jsonData); i++ { 
     w.Write(jsonData.Photos.Photo[i].Id) 
    } 
} 

回答

1

問題ISN:下面

cannot use jsonData.Photos.Photo[i].Id (type int) as type []byte in argument to w.Write 

我的代碼給出用你的模型,這工作得很好。當發生錯誤時,您已經完成反序列化(沒有錯誤); w.Write(jsonData.Photos.Photo[i].Id)。當它需要是一個字節數組時,你傳遞一個int。

這個答案解釋瞭如何做轉換; Convert an integer to a byte array

所以,要讓你的代碼變成一些工作形式;

import "encoding/binary" 

buffer := make([]byte, 4) 
for i := 0;i < len(jsonData.Photos.Photo); i++ { 
     binary.LittleEndian.PutUint32(buffer, jsonData.Photos.Photo[i].Id) 
     w.Write(buffer) 
    } 

請注意,將值的二進制表示形式作爲無符號32位int寫入,並帶有小端位順序。那可能不會爲你工作。如果你需要簽名和未簽名的ect,我不能說你會得到什麼樣的決定,比如你想要什麼位的順序。

編輯:爲了使上述工作,我想你必須做一個從int到uint32以及。更仔細地看看我聯繫你的答案可以做到這一點,而不是更清潔/更簡單的IMO。

import "strconv" 

for _, p := range jsonData.Photos.Photo { 
      w.Write([]byte(strconv.Itoa(p.Id))) 
     } 

第二次編輯:有很多方法可以將int轉換爲二進制。另一個好的選擇是; func Write(w io.Writer, order ByteOrder, data interface{}) error

我相信你的代碼你可以使用類似的;

import "encoding/binary" 

    for i := range jsonData.Photo.Photos { 
      binary.Write(w, binary.LittleEndian, jsonData.Photos.Photo[i].Id) 
     } 

http://golang.org/pkg/encoding/binary/#Write

編輯:更新了三個例子來對不同品種的循環工作。

+0

感謝您的幫助..但我仍然得到一個錯誤:不能使用jsonData.Photos.Photo [i] .Id(類型爲int)作爲參數類型uint32 binary.LittleEndian.PutUint32 – KrithGhosh

+0

@ user3502049啊是的,我應該看過方法定義。我會用更好的選項編輯。你可以從int到uint32進行另一次投射,但無論如何,我認爲這更容易。 – evanmcdonnal

+0

我試着用第一次編輯替換代碼,但仍然收到錯誤:無效的參數jsonData(type * Result)對於len – KrithGhosh