如何用Golang解碼巢狀的JSON,是許多開發者在處理複雜資料結構時所面臨的挑戰。在這篇文章中,php小編香蕉將為您詳細介紹如何使用Golang中的JSON套件來解析和處理巢狀的JSON資料。透過學習本文的內容,您將能夠輕鬆處理各種複雜的JSON結構,實現更有效率的資料解析和處理。無論您是初學者還是有一定經驗的開發者,本文都將為您提供有用的技巧和範例程式碼,幫助您解決JSON解碼的難題。讓我們一起來探索Golang中解碼嵌套JSON的方法吧!
我正在嘗試將巢狀 json 解碼為包含檔案和資料的請求的一部分。
資料看起來像這樣
{data: {"date_required":null}}
我原本沒有包含完整的錯誤,因為我忘記記錄它。
2023/11/17 23:40:35 error in decoding request body data 2023/11/17 23:40:35 invalid character '.' looking for beginning of value
我認為此錯誤可能是由於表單資料不是 JSON 造成的,但不知道如何修復它。我的 Flutter 程式碼看起來就像是發送了有效的 JSON。內容類型是 multipart/form-data
這可能是導致錯誤的原因。我相信我的程式碼的文件上傳部分需要此內容類型。
請求來自我的 Flutter 用戶端,程式碼如下:
final multipartFile = http.MultipartFile.fromBytes('file', bytes, filename: file?.name); final request = http.MultipartRequest('POST', Uri.parse(user.fileUrl)); request.files.add(multipartFile); request.headers.addAll(headers); String dateRequiredStr = dateRequired != null ? jsonEncode({'date_required': dateRequired}) : jsonEncode({'date_required': null}); request.fields['data'] = dateRequiredStr;
在我的 go API 中我正在這樣做。
模型(根據下面的答案進行編輯):
type FileRequiredDate struct { DateRequired pgtype.Date `json:"date_required"` } type FileRequiredDateData struct { Data FileRequiredDate `json:"data"` }
程式碼:
func (rs *appResource) uploadTranscriptAudioFile(w http.ResponseWriter, r *http.Request) { start := time.Now() const maxUploadSize = 500 * 1024 * 1024 // 500 Mb var requiredByDate FileRequiredDateData decoder := json.NewDecoder(r.Body) err := decoder.Decode(&requiredByDate) if err != nil { log.Println("error in decoding request body data") log.Println(err.Error()) http.Error(w, err.Error(), http.StatusBadRequest) return } file, handler, err := r.FormFile("file") if err != nil { log.Println(err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } defer file.Close() fileSize := handler.Size if fileSize > maxUploadSize { http.Error(w, "FILE_TOO_BIG", http.StatusBadRequest) return } fileName := handler.Filename
httputil.DumpRequest
-> 內容類型:multipart/form-data
編輯:根據這個問題的答案,我編輯瞭如下程式碼:
mr, err := r.MultipartReader() if err != nil { log.Println(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } for { part, err := mr.NextPart() // This is OK, no more parts if err == io.EOF { break } // Some error if err != nil { log.Println("multipart reader other error") http.Error(w, err.Error(), http.StatusInternalServerError) return } log.Println(part.FormName()) if part.FormName() == "data" { log.Println("multipart reader found multipart form name data") decoder := json.NewDecoder(r.Body) err = decoder.Decode(&requiredByDate) if err != nil { log.Println("error in decoding request body data") log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } } } if part.FormName() == "file" { file, handler, err := r.FormFile("file") <-- error here if err != nil { log.Println("error getting form file") log.Println(err.Error()) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusInternalServerError) return } defer file.Close() guid := xid.New() userId := getUserFromJWT(r) user, err := getUser(rs, int64(userId)) if err != nil { log.Println("user not found") log.Println(err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } err = uploadToMinio(rs, file, fileSize, fileName, guid.String(), userId) ----
這給了我這個輸出:
2023/11/17 23:23:30 data 2023/11/17 23:23:30 file
編輯:
我透過使用 decoder := json.NewDecoder(part)
而不是 decoder := json.NewDecoder(r.Body)
解決了當前問題
現在我在取得表單檔案時遇到錯誤。看來我應該以某種方式使用零件,但零件沒有文件屬性。自從我將表單資料新增至多部分請求後,r.Body 不再可用。這看起來像是不同的問題。
雖然這不能解決 404 問題(請使用請求處理程序程式碼更新您的問題),但您的結構似乎與您發送的內容不符。您可以執行以下操作來解決此問題:
type FileRequiredDate struct { DateRequired pgtype.Date `json:"date_required"` } type FileRequiredDateData struct { Data FileRequiredDate `json:"data"` }
這應該可以按預期解碼請求正文。
對於 404,您應該仔細檢查客戶端程式碼發送的請求路徑和方法是否與伺服器請求處理程序路徑和方法相符。
以上是如何用 Golang 解碼這個巢狀的 json?的詳細內容。更多資訊請關注PHP中文網其他相關文章!