Итак, у меня есть следующее, которое кажется невероятным, и я подумал, что Go имеет лучше спроектированные библиотеки, чем этот, но я не могу найти пример того, как Go обрабатывает POST-запрос данных JSON. Все они представляют собой посты.
Вот пример запроса: 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 для поисковых систем и упоминается здесь, чтобы другие могли его найти.)
curl -X POST -H 'Content-Type: application/json' -d "{\"test\": \"that\"}"
, тоreq.Form["test"]
должны вернуться"that"
Ответы:
Пожалуйста, используйте
json.Decoder
вместоjson.Unmarshal
.источник
defer req.Body.Close()
Из документов: «Сервер закроет тело запроса. Обработчику ServeHTTP это не нужно». Также, чтобы ответить на @thisisnotabus, из документов: «Для запросов к серверу тело запроса всегда не равно нулю, но будет возвращать EOF немедленно, когда тела нет» golang.org/pkg/net/http/#Requestjson.Decoder
. Он предназначен для потоков объектов JSON, а не для одного объекта. Это не более эффективно для одного объекта JSON, так как он считывает весь объект в память. Недостатком является то, что если мусор включается после объекта, он не будет жаловаться. В зависимости от нескольких факторов,json.Decoder
возможно, не полностью прочитать тело и соединение не будет иметь право на повторное использование.Вам нужно читать с
req.Body
.ParseForm
Метод чтения отreq.Body
и затем разбор его в стандартном формате HTTP закодированной. Вам нужно прочитать тело и разобрать его в формате JSON.Вот ваш код обновлен.
источник
req.ParseForm()
, что я делал в более ранних попытках решить эту проблему, перед тем, как вы попытаетесь прочитатьreq.Body
, он, кажется, очищает тело иunexpected end of JSON input
выбрасывается, когда вы переходитеUnmarshal
(по крайней мере, в 1.0.2)json.NewDecoder(req.Body)
, также являются правильными.Я сводил себя с ума с этой точной проблемой. Мой JSON Marshaller и Unmarshaller не заполняли мою структуру Go. Затем я нашел решение по адресу https://eager.io/blog/go-and-json :
После этого мои маршаллеры и унмаршаллеры сработали отлично!
источник
Есть две причины, по которым
json.Decoder
следует отдавать предпочтение,json.Unmarshal
- они не рассматриваются в самом популярном ответе 2013 года:go 1.10
представил новый метод json.Decoder.DisallowUnknownFields (), который решает проблему обнаружения нежелательного JSON-вводаreq.Body
это ужеio.Reader
. Считывание всего содержимого и последующее использованиеjson.Unmarshal
ненужных ресурсов, если поток был, скажем, 10-мегабайтным блоком недопустимого JSON. Синтаксический анализ тела запроса приjson.Decoder
его поступлении вызовет ошибку раннего разбора, если будет обнаружен недопустимый JSON. Обработка потоков ввода / вывода в реальном времени является предпочтительным способом .Обращаясь к некоторым комментариям пользователя об обнаружении неправильного ввода пользователя:
Чтобы ввести обязательные поля и другие санитарные проверки, попробуйте:
Игровая площадка
Типичный вывод:
источник
Я нашел следующий пример из документации действительно полезным (источник здесь ).
Ключевым моментом здесь является то, что ОП пытался декодировать
... в этом случае мы удалили бы
const jsonStream
и заменилиMessage
структуру наtest_struct
:Обновление : я также хотел бы добавить, что в этом посте представлены отличные данные об ответах с помощью JSON. Автор объясняет
struct tags
, о чем я не знал.Поскольку JSON обычно выглядит не так
{"Test": "test", "SomeKey": "SomeVal"}
, а наоборот{"test": "test", "somekey": "some value"}
, вы можете реструктурировать свою структуру следующим образом:... и теперь ваш обработчик будет анализировать JSON, используя "some-key" вместо "SomeKey" (который вы будете использовать внутри).
источник
источник