이동 시 JSON Post Request 처리
저는 다음과 같은 것을 가지고 있습니다.놀라운 해킹으로 보입니다.Go가 이것보다 더 나은 라이브러리를 설계했다고 생각해 왔습니다만, Go가 JSON 데이터의 POST 요구를 처리하는 예를 찾을 수 없습니다.이것들은 모두 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이라고도 하며, 다른 사람이 찾을 수 있도록 여기에 언급되어 있습니다.)
사용하세요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)
}
에서 읽을 필요가 있습니다.req.Body
.그ParseForm
method는 에서 읽고 있습니다.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))
}
두 가지 이유가 있다json.Decoder
보다 우선되어야 한다json.Unmarshal
- 2013년 이후 가장 인기 있는 답변에서 다루지 않은 내용:
- 2018년 2월
go 1.10
새로운 메서드 json을 도입했습니다.디코더허가하지 않다Unknown Fields(): 불필요한 JSON 입력 검출 우려에 대처합니다. req.Body
이미 이 되어 있다io.Reader
. 전체 내용을 읽은 후 수행json.Unmarshal
예를 들어 유효하지 않은 JSON의 10MB 블록이 스트림일 경우 리소스가 낭비됩니다.요청 본문 해석, 사용json.Decoder
유효하지 않은 JSON이 발생했을 경우 초기 해석 오류가 발생합니다.I/O 스트림을 실시간으로 처리하는 것이 좋습니다.
잘못된 사용자 입력 검출에 관한 사용자 코멘트의 일부에 대처합니다.
필수 필드 및 기타 위생 체크를 적용하려면 다음을 수행합니다.
d := json.NewDecoder(req.Body)
d.DisallowUnknownFields() // catch unwanted fields
// anonymous struct type: handy for one-time use
t := struct {
Test *string `json:"test"` // pointer so we can test for field absence
}{}
err := d.Decode(&t)
if err != nil {
// bad JSON or unrecognized json field
http.Error(rw, err.Error(), http.StatusBadRequest)
return
}
if t.Test == nil {
http.Error(rw, "missing field 'test' from JSON object", http.StatusBadRequest)
return
}
// optional extra check
if d.More() {
http.Error(rw, "extraneous data after JSON object", http.StatusBadRequest)
return
}
// got the input we expected: no more, no less
log.Println(*t.Test)
일반적인 출력:
$ curl -X POST -d "{}" http://localhost:8082/strict_test
expected json field 'test'
$ curl -X POST -d "{\"Test\":\"maybe?\",\"Unwanted\":\"1\"}" http://localhost:8082/strict_test
json: unknown field "Unwanted"
$ curl -X POST -d "{\"Test\":\"oops\"}g4rB4g3@#$%^&*" http://localhost:8082/strict_test
extraneous data after JSON
$ curl -X POST -d "{\"Test\":\"Works\"}" http://localhost:8082/strict_test
log: 2019/03/07 16:03:13 Works
나는 이 문제 때문에 미칠 지경이었다.나의 JSON Marshaller와 Unmarshaller는 나의 바둑 구조를 채우지 않았다.그 후, https://eager.io/blog/go-and-json 에서 솔루션을 찾았습니다.
"Go의 모든 구조물과 마찬가지로 JSON Marshaller와 같은 외부 프로그램에서는 첫 글자가 대문자로 표시된 필드만 표시된다는 점을 기억해야 합니다."
그 후, 내 마샬러와 언마샬러는 완벽하게 작동했어!
다음의 문서의 예는 매우 도움이 되었습니다(여기서 출처를 참조).
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)
}
}
여기서 중요한 건 작전본부가 해독하려고 했던 게
type test_struct struct {
Test string
}
경우 는 ...을 떨어뜨릴 이다.이경,, 리는그그그그떨떨떨떨떨것것것것것것것것.const jsonStream
Message
와 함께 구조화하다test_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
내가 몰랐던 것 같아요
JSON처럼 않기 때문에{"Test": "test", "SomeKey": "SomeVal"}
, '''가 아니라{"test": "test", "somekey": "some value"}
다음과 같이 구조를 재구성할 수 있습니다.
type test_struct struct {
Test string `json:"test"`
SomeKey string `json:"some-key"`
}
...이제 핸들러는 내부에서 사용하는 "SomeKey"가 아닌 "some-key"를 사용하여 JSON을 해석합니다.
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)
}
커스텀 구조를 로컬로 정의하는 것을 좋아합니다.그래서:
// my handler func
func addImage(w http.ResponseWriter, r *http.Request) {
// define custom type
type Input struct {
Url string `json:"url"`
Name string `json:"name"`
Priority int8 `json:"priority"`
}
// define a var
var input Input
// decode input or return error
err := json.NewDecoder(r.Body).Decode(&input)
if err != nil {
w.WriteHeader(400)
fmt.Fprintf(w, "Decode error! please check your JSON formating.")
return
}
// print user inputs
fmt.Fprintf(w, "Inputed name: %s", input.Name)
}
언급URL : https://stackoverflow.com/questions/15672556/handling-json-post-request-in-go
'programing' 카테고리의 다른 글
작곡가 "경로" 리포지토리가 작동하도록 가져올 수 없습니다. (0) | 2023.02.11 |
---|---|
RegExp의 시리얼화 (0) | 2023.02.11 |
Oracle 테이블에서 중복된 값을 찾으려면 어떻게 해야 합니까? (0) | 2023.02.11 |
데이터가 도착하기 전에 ng-src가 이미지를 로드하지 않도록 하려면 어떻게 해야 합니까? (0) | 2023.02.11 |
Angularjs: 명령어에 스코프 변수를 전달하려면 어떻게 해야 합니까? (0) | 2023.02.11 |