Golang json Unmarshal "неожиданный конец ввода JSON"

Я работаю над некоторым кодом для анализа данных JSON из ответа HTTP. Код, который у меня есть, выглядит примерно так:

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

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

json в переменной respBytes выглядит следующим образом:

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

Однако err не равен нулю. Когда я его распечатаю, он говорит unexpected end of JSON input. Чем это вызвано? Кажется, что JSON действительно. Эта ошибка имеет какое-то отношение к моей настраиваемой структуре?

Спасибо заранее!

Ответ 1

unexpected end of JSON input является результатом синтаксической ошибки на входе JSON (вероятно, отсутствует ", } или ]). Ошибка не зависит от типа значения, которое вы декодируете.

Я запустил код с примером ввода JSON на игровой площадке. Он работает без ошибок.

Код не декодирует ничего, потому что поле result не экспортируется. Если вы экспортируете поле результата:

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

тогда вход декодируется, как показано в этом примере игровой площадки.

Я подозреваю, что вы не читаете весь орган ответа в своем приложении. Я предлагаю декодировать вход JSON, используя:

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

Декодер считывает непосредственно из тела ответа.

Ответ 2

Вы также можете получить эту ошибку, если используете json.RawMessage в нераспределенном поле. Например, следующий код создает ту же ошибку:

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)
}

Если вы экспортируете поле "MyJson.bar" (например, → "MyJson.Bar", то код работает.