web-dev-qa-db-fra.com

Golang json Unmarshal "fin inattendue de l'entrée JSON"

Je travaille sur du code pour analyser les données JSON à partir d'une réponse HTTP. Le code que j'ai a quelque chose comme ça:

type ResultStruct struct {
    result []map[string]string
}

var jsonData ResultStruct
err = json.Unmarshal(respBytes, &jsonData)

Le json dans la variable respBytes ressemble à ceci:

{
 "result": [
  {
   "id": "ID 1"
  },
  {
   "id": "ID 2"
  }
 ]
}

Cependant, err n'est pas nul. Quand je l’imprime, il est écrit unexpected end of JSON input. Qu'est-ce qui cause ça? Le JSON semble être valide. Cette erreur a-t-elle quelque chose à voir avec ma structure personnalisée?

Merci d'avance!

9
Stratus3D

unexpected end of JSON input est le résultat de une erreur de syntaxe dans l'entrée JSON (probablement un ", } ou ] manquant. L'erreur ne dépend pas du type de la valeur que vous décodez.

J'ai exécuté le code avec l'exemple d'entrée JSON sur le terrain de jeu . Il fonctionne sans erreur.

Le code ne décode rien car le champ result n'est pas exporté. Si vous exportez le champ de résultat:

type ResultStruct struct {
   Result []map[string]string
}

ensuite, l’entrée est décodée comme indiqué dans cet exemple playground .

Je suppose que vous ne lisez pas tout le corps de la réponse dans votre application. Je suggère de décoder l'entrée JSON en utilisant:

err := json.NewDecoder(resp.Body).Decode(&jsonData)

Le décodeur lit directement à partir du corps de la réponse.

4
ThunderCat

Vous pouvez également obtenir cette erreur si vous utilisez json.RawMessage dans un champ non exporté. Par exemple, le code suivant produit la même erreur:

package main

import (
    "encoding/json"
    "fmt"
)

type MyJson struct {
    Foo bool `json:"foo"`
    bar json.RawMessage `json:"bar"`
}

type Bar struct {
    X int `json:"x"`
}

var respBytes = []byte(`
{
  "foo": true,
  "bar": { "x": 10 }
}`)

func main() {
    var myJson MyJson
    err := json.Unmarshal(respBytes, &myJson)
    if err != nil {
        fmt.Println(err)
        return
    }
    myBar := new(Bar)
    err = json.Unmarshal(myJson.bar, myBar)
    fmt.Println(err)
}

Si vous exportez le champ "MyJson.bar" (par exemple -> "MyJson.Bar", le code fonctionne.

2
Robert

J'ai rencontré la même erreur en essayant d'utiliser une requête select de la base de données (à l'aide de sqlx).

Le code ressemblait à ceci:

result := []*userRow{}
err := q.Select(&result, getUserByIDQuery, userID)
if err != nil {
    return false, e.Error(codes.Internal, e.DBError, err)
}

Où userRow est défini comme 

type userRow struct {
    UserId        string
    FirstName     string
    LastName      string
}

Pour résoudre le problème que j'ai eu, j'ai ajouté une balise db à la structure:

type userRow struct {
    UserId        string `db:"user_id"`
    FirstName     string `db:"first_name"`
    LastName      string `db:"last_name"`
}

J'espère que cela peut aider quelqu'un dans la furute.

0
Daniel Shterenberg