Cara menyahkod JSON bersarang dengan Golang ialah cabaran yang dihadapi oleh ramai pembangun apabila berurusan dengan struktur data yang kompleks. Dalam artikel ini, editor PHP Banana akan memperkenalkan anda secara terperinci cara menggunakan pakej JSON di Golang untuk menghuraikan dan memproses data JSON bersarang. Dengan mengkaji kandungan artikel ini, anda akan dapat mengendalikan pelbagai struktur JSON yang kompleks dengan mudah dan mencapai penghuraian dan pemprosesan data yang lebih cekap. Sama ada anda seorang pemula atau pembangun yang berpengalaman, artikel ini akan memberikan anda petua berguna dan kod contoh untuk membantu anda menyelesaikan masalah sukar penyahkodan JSON. Mari terokai kaedah penyahkodan JSON bersarang di Golang!
Saya cuba menyahkod json bersarang sebagai sebahagian daripada permintaan yang mengandungi fail dan data.
Data kelihatan seperti ini
{data: {"date_required":null}}
Saya tidak memasukkan ralat penuh pada mulanya kerana saya terlupa untuk mendokumentasikannya.
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
Saya rasa ralat ini mungkin disebabkan oleh data borang yang bukan JSON, tetapi tidak tahu cara membetulkannya. Kod Flutter saya kelihatan seperti menghantar JSON yang sah. Jenis kandungan ialah multipart/form-data
Ini mungkin menyebabkan ralat. Saya percaya jenis kandungan ini diperlukan untuk bahagian muat naik fail kod saya.
Permintaan datang dari pelanggan Flutter saya, kodnya adalah seperti berikut:
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;
Dalam API saya, saya melakukan ini.
Model (diedit berdasarkan jawapan di bawah):
type FileRequiredDate struct { DateRequired pgtype.Date `json:"date_required"` } type FileRequiredDateData struct { Data FileRequiredDate `json:"data"` }
Kod:
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
-> Jenis kandungan: berbilang bahagian/data-bentuk
Sunting: Berdasarkan jawapan kepada soalan ini, saya menyunting kod seperti berikut:
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) ----
Ini memberikan saya output ini:
2023/11/17 23:23:30 data 2023/11/17 23:23:30 file
Editor:
Saya menyelesaikan masalah semasa dengan menggunakan decoder := json.NewDecoder(part)
而不是 decoder := json.NewDecoder(r.Body)
Kini saya mendapat ralat semasa mendapatkan fail borang . Nampaknya saya harus menggunakan bahagian itu entah bagaimana, tetapi bahagian itu tidak mempunyai sifat fail. Memandangkan saya menambahkan data borang pada permintaan berbilang bahagian, r.Body tidak lagi tersedia. Ini kelihatan seperti masalah yang berbeza.
Walaupun ini tidak membetulkan isu 404 (sila kemas kini soalan anda dengan kod pengendali permintaan), struktur anda nampaknya tidak sepadan dengan apa yang anda hantar. Anda boleh melakukan perkara berikut untuk menyelesaikan masalah ini:
type FileRequiredDate struct { DateRequired pgtype.Date `json:"date_required"` } type FileRequiredDateData struct { Data FileRequiredDate `json:"data"` }
Ini sepatutnya menyahkod badan permintaan seperti yang diharapkan.
Untuk 404, anda harus menyemak semula bahawa laluan permintaan dan kaedah yang dihantar oleh kod klien sepadan dengan laluan dan kaedah pengendali permintaan pelayan.
Atas ialah kandungan terperinci Bagaimana untuk menyahkod json bersarang ini dengan Golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!