Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menyahkod json bersarang ini dengan Golang?

Bagaimana untuk menyahkod json bersarang ini dengan Golang?

WBOY
WBOYke hadapan
2024-02-10 18:45:08980semak imbas

如何用 Golang 解码这个嵌套的 json?

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!

Kandungan soalan

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.

Penyelesaian

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam