300

これは信じられないほどハックに思えます.Goにはこれよりも優れた設計のライブラリがあると考えていましたが、JSONデータのPOSTリクエストを処理するGoの例を見つけることができません. それらはすべてフォーム POST です。

リクエストの例を次に示します。curl -X POST -d "{\"test\": \"that\"}" http://localhost:8082/test

ログが埋め込まれたコードは次のとおりです。

package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type test_struct struct {
    Test string
}

func test(rw http.ResponseWriter, req *http.Request) {
    req.ParseForm()
    log.Println(req.Form)
    //LOG: map[{"test": "that"}:[]]
    var t test_struct
    for key, _ := range req.Form {
        log.Println(key)
        //LOG: {"test": "that"}
        err := json.Unmarshal([]byte(key), &t)
        if err != nil {
            log.Println(err.Error())
        }
    }
    log.Println(t.Test)
    //LOG: that
}

func main() {
    http.HandleFunc("/test", test)
    log.Fatal(http.ListenAndServe(":8082", nil))
}

もっと良い方法があるはずですよね?私はベストプラクティスが何であるかを見つけることに困惑しています。

(Go は検索エンジンでは Golang としても知られており、他の人が見つけられるようにここで言及しています。)

4

7 に答える 7

444

json.Decoderの代わりに使用してくださいjson.Unmarshal

func test(rw http.ResponseWriter, req *http.Request) {
    decoder := json.NewDecoder(req.Body)
    var t test_struct
    err := decoder.Decode(&t)
    if err != nil {
        panic(err)
    }
    log.Println(t.Test)
}
于 2013-03-28T15:11:53.443 に答える
98

から読む必要がありますreq.BodyParseFormメソッドは から読み取り、req.Body標準の HTTP エンコード形式で解析します。必要なのは、本文を読み取って JSON 形式で解析することです。

これでコードが更新されました。

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "io/ioutil"
)

type test_struct struct {
    Test string
}

func test(rw http.ResponseWriter, req *http.Request) {
    body, err := ioutil.ReadAll(req.Body)
    if err != nil {
        panic(err)
    }
    log.Println(string(body))
    var t test_struct
    err = json.Unmarshal(body, &t)
    if err != nil {
        panic(err)
    }
    log.Println(t.Test)
}

func main() {
    http.HandleFunc("/test", test)
    log.Fatal(http.ListenAndServe(":8082", nil))
}
于 2013-03-28T01:24:28.913 に答える
72

私はこの正確な問題に夢中になっていました。JSON Marshaller と Unmarshaller が Go 構造体にデータを入力していませんでした。次に、https : //eager.io/blog/go-and-json で解決策を見つけました。

「Go のすべての構造体と同様に、最初の文字が大文字のフィールドのみが JSON Marshaller のような外部プログラムに表示されることを覚えておくことが重要です。」

その後、私のマーシャラーとアンマーシャラーは完全に機能しました!

于 2016-03-15T00:01:24.680 に答える
21

ドキュメントの次の例が非常に役立つことがわかりました(ソースはこちら)。

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "log"
    "strings"
)

func main() {
    const jsonStream = `
        {"Name": "Ed", "Text": "Knock knock."}
        {"Name": "Sam", "Text": "Who's there?"}
        {"Name": "Ed", "Text": "Go fmt."}
        {"Name": "Sam", "Text": "Go fmt who?"}
        {"Name": "Ed", "Text": "Go fmt yourself!"}
    `
    type Message struct {
        Name, Text string
    }
    dec := json.NewDecoder(strings.NewReader(jsonStream))
    for {
        var m Message
        if err := dec.Decode(&m); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s: %s\n", m.Name, m.Text)
    }
}

ここで重要なのは、OPがデコードしようとしていたことです

type test_struct struct {
    Test string
}

...その場合、 を削除し、構造体を:const jsonStreamに置き換えます。Messagetest_struct

func test(rw http.ResponseWriter, req *http.Request) {
    dec := json.NewDecoder(req.Body)
    for {
        var t test_struct
        if err := dec.Decode(&t); err == io.EOF {
            break
        } else if err != nil {
            log.Fatal(err)
        }
        log.Printf("%s\n", t.Test)
    }
}

更新:この投稿では、JSON での応答に関する優れたデータも提供されていることも付け加えておきます。筆者はstruct tags、私が知らなかった を説明します。

{"Test": "test", "SomeKey": "SomeVal"}JSON は通常ではなくのように見えるため{"test": "test", "somekey": "some value"}、次のように構造体を再構築できます。

type test_struct struct {
    Test string `json:"test"`
    SomeKey string `json:"some-key"`
}

...これで、ハンドラーは "SomeKey" (内部で使用する) ではなく、"some-key" を使用して JSON を解析します。

于 2015-04-17T01:48:03.233 に答える
4
type test struct {
    Test string `json:"test"`
}

func test(w http.ResponseWriter, req *http.Request) {
    var t test_struct

    body, _ := ioutil.ReadAll(req.Body)
    json.Unmarshal(body, &t)

    fmt.Println(t)
}
于 2020-01-21T23:59:04.063 に答える