Печать данных POST JSON - PullRequest
       16

Печать данных POST JSON

0 голосов
/ 09 февраля 2019

У меня проблема с печатью JSON из сообщения.Я использую MUX для маршрутизации

r := mux.NewRouter()
r.HandleFunc("/test", Point).Methods("POST")
http.ListenAndServe(":80", r)`

и в функции Point у меня есть

func Point(w http.ResponseWriter, r *http.Request) {
    var callback Decoder
    json.NewDecoder(r.Body).Decode(&callback)
}

Но я могу использовать этот метод только тогда, когда я знаю структуру и хочу выяснить, как войти. Распечатать весь JSON в виде строки.Я пытался

func Point(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    log.Println(r.Form)
} 

Но он печатал пустую карту.Пожалуйста, помогите разобраться в этом.

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

В предположении, что вы создаете стандартную конечную точку API, которая получает некоторый JSON, и вы хотели бы что-то с ним сделать, вы должны подойти к нему следующим образом.

Редактировать:

Как уже упоминалось в комментариях, когда вы используете функцию ioutil.ReadAll (), как в этом примере, она будет читать все, что отправлено в запросе post, в память приложения.Это хорошая идея, чтобы проверить это в производственном приложении (например, ограничение размера полезной нагрузки).

1.) Создайте структуру, которая будет содержать данные, поступающие из пост-запроса API в GoLang
2..) Преобразуйте тело вашего запроса в байтовый массив []byte
3.) Unmarshal ваш []byte в один экземпляр вашей структуры, созданный ранее.

Я приведу пример ниже:

1.Создайте структуру, в которую вы поместите свой JSON.


Давайте рассмотрим пример простого поста в блоге.

Объект JSON выглядит следующим образом и имеет slug, title и description

{
  "slug": "test-slug",
  "title": "This is the title",
  "body": "This is the body of the page"
}

Таким образом, ваша структура будет выглядеть следующим образом:

type Page struct {
    Slug  string `json:"slug"`
    Title string `json:"title"`
    Body  string `json:"body"`
}

2 - 3. Получите тело вашего запроса и преобразуйте его в byte[] Затем возьмите эту строку и Unmarshal в экземпляр вашей структуры.


Данныеpost request - это запрос 'Body'.

В Golang запрос почти во всех случаях (если вы не используете что-то необычное, кроме значений по умолчанию) будет объектом http.Request.Это «r», которое у вас обычно есть в вашем обычном коде, и оно содержит «Body» нашего POST-запроса.

import (
    "encoding/json"
    "github.com/go-chi/chi" // you can remove
    "github.com/go-chi/render" // you can remove but be sure to remove where it is used as well below.
    "io/ioutil"
    "net/http"
)


func GiveMeAPage(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("A page"))
}

Итак, что мы собираемся здесь сделать, это преобразовать io.ReadCloser,это то, что http.Request.Body, к []byte, поскольку функция Unmarshal принимает тип []byte.Я прокомментировал ниже для вас.

func Create(w http.ResponseWriter, r *http.Request) {
    var p Page //Create an instance of our struct


    //Read all the data in r.Body from a byte[], convert it to a string, and assign store it in 's'.
    s, err := ioutil.ReadAll(r.Body) 
    if err != nil {
        panic(err) // This would normally be a normal Error http response but I've put this here so it's easy for you to test.
    }
    // use the built in Unmarshal function to put the string we got above into the empty page we created at the top.  Notice the &p.  The & is important, if you don't understand it go and do the 'Tour of Go' again.
    err = json.Unmarshal(s, &p)
    if err != nil {
        panic(err) // This would normally be a normal Error http response but I've put this here so it's easy for you to test.
    }

   // From here you have a proper Page object which is filled.  Do what you want with it.

    render.JSON(w, r, p) // This is me using a useful helper function from go-chi which 'Marshals' a struct to a json string and returns it to using the http.ResponseWriter.
}

В качестве примечания.Пожалуйста, не используйте Decoder для анализа JSON, если вы не используете потоки JSON.Вы не здесь, и вряд ли вы будете некоторое время.Вы можете прочитать о том, почему это здесь

0 голосов
/ 09 февраля 2019

Если вам просто нужны необработанные данные JSON без их анализа, http.Request.Body реализует io.Reader, поэтому вы можете просто Read получить их.Например, с ioutil.ReadAll.

Что-то вроде (не проверено):

func Point(w http.ResponseWriter, r *http.Request) {
    data, err := ioutil.ReadAll(r.Body)
    // check error
    // do whatever you want with the raw data (you can `json.Unmarshal` it too)
}
...