Bagaimana untuk menyahkod json bersarang ini dengan Golang?

WBOY
Lepaskan: 2024-02-10 18:45:08
ke hadapan
980 orang telah melayarinya

如何用 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}}
Salin selepas log masuk

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
Salin selepas log masuk

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;
Salin selepas log masuk

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"`
}
Salin selepas log masuk

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
Salin selepas log masuk

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)


----
Salin selepas log masuk

Ini memberikan saya output ini:

2023/11/17 23:23:30 data
2023/11/17 23:23:30 file
Salin selepas log masuk

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"`
}
Salin selepas log masuk

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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!