2013-06-22 62 views
1

我對提出了很高的歉意,提出了很長的問題。希望你能忍受我。將複雜的JSON解析爲goweb REST Create()函數

我正在使用goweb庫,並試用了example web app

我一直試圖修改RESTful example code,它定義了Thing爲:

type Thing struct { 
    Id string 
    Text string 
} 

Thing通過發送一個請求HTTP Post,用適當的JSON身體,http://localhost:9090/things創建。這在實施例中的代碼Create function處理,具體地,行:

dataMap := data.(map[string]interface{}) 

thing := new(Thing) 
thing.Id = dataMap["Id"].(string) 
thing.Text = dataMap["Text"].(string) 

這一切都很好,我可以運行該示例服務器(它偵聽http://localhost:9090/)和服務器作爲預期操作。

例如:

curl -X POST -H "Content-Type: application/json" -d '{"Id":"TestId","Text":"TestText"}' http://localhost:9090/things 

返回,沒有錯誤,然後我GETThing

curl http://localhost:9090/things/TestId 

,並返回

{"d":{"Id":"TestId","Text":"TestText"},"s":200} 

到目前爲止,一切都很好。現在

,我想修改Thing類型,並添加自定義ThingText類型,就像這樣:

type ThingText struct { 
    Title string 
    Body string 
} 

type Thing struct { 
    Id string 
    Text ThingText 
} 

這本身不是一個問題,我可以修改Create功能,像這樣:

thing := new(Thing) 
thing.Id = dataMap["Id"].(string) 
thing.Text.Title = dataMap["Title"].(string) 
thing.Text.Body = dataMap["Body"].(string) 

和運行以前curlPOST請求與JSON設置爲:

{"Id":"TestId","Title":"TestTitle","Title":"TestBody"} 

並且返回時沒有錯誤。

我再次可以GETThing URL,它返回:

{"d":{"Id":"TestId","Text":{"Title":"TestTitle","Body":"TestBody"}},"s":200} 

再次,到目前爲止,一切都很好。

現在,我的問題:

我怎麼修改Create功能讓我POST複雜JSON呢?

例如,最後返回的JSON以上字符串包括{"Id":"TestId","Text":{"Title":"TestTitle","Body":"TestBody"}}我希望能夠將POST確切地說JSON添加到端點並創建了Thing

我已經按照該代碼後面,它似乎是data變量是Context.RequestData()類型的從https://github.com/stretchr/goweb/context,並且內部Map似乎從https://github.com/stretchr/stew/,被描述爲在特定"a map[string]interface{} with additional helpful functionality."Object.Map類型的,我注意到"Supports dot syntax to set deep values."

我不知道如何設置thing.Text.Title = dataMap...語句,以便將正確的JSON字段解析爲它。我似乎不能在dataMap使用比string類型的其他任何東西,如果我嘗試JSON它給出類似的錯誤:

http: panic serving 127.0.0.1:59113: interface conversion: interface is nil, not string 

再次,比較遺憾的是可笑長的問題。我非常感謝您閱讀,以及您可能提供的任何幫助。謝謝!

+0

既然您已經發布了tl; dr問題,請發佈我們可能會閱讀的問題。 – peterSO

回答

3

正如JSON package documentationJSON and Go introduction所描述的,JSON數據可以通過接口{} /字符串映射或直接解組結構類型來解析。

您鏈接到的基於您的更改的示例代碼似乎使用通用字符串映射方法dataMap := data.(map[string]interface{})

由於您所需的JSON數據是對象中的對象,因此它只是地圖內的地圖。

所以,你應該能夠

dataMap := data.(map[string]interface{}) 
subthingMap := dataMap["Text"].(map[string]interface{}) 
thing.Text.Title = subthingMap["Title"].(string) 
thing.Text.Body = subthingMap["Body"].(string) 

我不知道爲什麼代碼使用管型和通用型與直接從JSON類型安全的解組,以結構類型(抽象我猜)。使用JSON包解組到結構類型會去像

type ThingText struct { 
    Title string 
    Body string 
} 

type Thing struct { 
    Id string 
    Text ThingText 
} 

… 
decoder := json.NewDecoder(body) 
var thingobj Thing 
for { 
    if err := decoder.Decode(&thingobj); err == io.EOF { 
     break 
    } else if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(thingobj) 
} 

其中bodyio.Reader - 簡單/大多數情況下http.Response.Body

+0

謝謝你,'subthingMap:= dataMap [「Text」]。(map [string] interface {})'工作。非常感激! – Intermernet