简体   繁体   English

Golang json 解组“JSON 输入的意外结束”

[英]Golang json Unmarshal "unexpected end of JSON input"

I am working on some code to parse the JSON data from an HTTP response.我正在编写一些代码来解析来自 HTTP 响应的 JSON 数据。 The code I have looks something like this:我的代码看起来像这样:

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

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

The json in the respBytes variable looks like this: respBytes变量中的 json 如下所示:

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

However, err is not nil.然而, err不是零。 When I print it out it says unexpected end of JSON input .当我打印出来时,它说unexpected end of JSON input What is causing this?这是什么原因造成的? The JSON seems to valid. JSON 似乎有效。 Does this error have something to do with my custom struct?此错误与我的自定义结构有关吗?

Thanks in advance!提前致谢!

The unexpected end of JSON input is the result of a syntax error in the JSON input (likely a missing " , } , or ] ). The error does not depend on the type of the value that you are decoding to. unexpected end of JSON inputunexpected end of JSON input的语法错误的结果(可能缺少"}] )。该错误与您要解码为的值的类型无关。

I ran the code with the example JSON input on the playground .在操场上使用示例 JSON 输入运行代码。 It runs without error.它运行没有错误。

The code does not decode anything because the result field is not exported.该代码不会解码任何内容,因为result字段未导出。 If you export the result field:如果导出结果字段:

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

then the input is decoded as shown in this playground example .然后输入被解码,如这个游乐场示例所示。

I suspect that you are not reading the entire response body in your application.我怀疑您没有阅读应用程序中的整个响应正文。 I suggest decoding the JSON input using:我建议使用以下方法解码 JSON 输入:

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

The decoder reads directly from the response body.解码器直接从响应正文中读取。

You can also get this error if you're using json.RawMessage in an unexported field.如果您在未导出的字段中使用 json.RawMessage,您也会收到此错误。 For example, the following code produces the same error:例如,以下代码会产生相同的错误:

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

If you export "MyJson.bar" field (eg -> "MyJson.Bar", then the code works.如果您导出“MyJson.bar”字段(例如 ->“MyJson.Bar”,则代码有效。

it is not the case here;这里不是这样; but if you are getting this error loading json from a file the Will occur if the byte slice for the buffer is not initialized the the byte size of the file.但是如果您在从文件加载 json 时遇到此错误,如果缓冲区的字节切片未初始化文件的字节大小,则会发生此错误。 [when you're new like me that happens! [当你像我一样是新人时,就会发生这种情况! ] Since this is the first search result I got it still took some digging to figure out. ] 由于这是我得到的第一个搜索结果,它仍然需要一些挖掘才能弄清楚。 In this use case the error is a bit misleading.在这个用例中,错误有点误导。

type GenesisResultStruct []GenesisField

fileinfo, _ := genesis.Stat()
bs := make([]byte, fileinfo.Size())
//bs := []byte {} // wrong!!
_, error := genesis.Read(bs)

if error != nil {
    fmt.Println("genesis read error: ", error)
    os.Exit(1)
}

var jsonData GenesisResultStruct
eGen = json.Unmarshal(bs, &jsonData)

if eGen != nil {
    fmt.Println("genesis unmarshal error: ", eGen)
    os.Exit(1)
}

Faced the same issue today.今天面临同样的问题。

You can also get this error if the respBytes is nil or there are no brackets [] if you are unmarshalling it to a slice.如果respBytesnil或没有括号[]如果您将其解组为切片,您也可能会收到此错误。 In that case, you need to explicitly set respBytes .在这种情况下,您需要显式设置respBytes

As you are unmarshalling it to a slice, brackets [] are expected in the byte-slice当您将其解组为切片时,字节切片中应使用括号[]

if src == nil {
    src = []byte("[]")
}

I encountered the same error while trying to using a select query from the DB (using sqlx). 尝试使用来自DB的select查询时(使用sqlx),我遇到了同样的错误。

The code was something like this: 代码是这样的:

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

Where userRow is defined like 其中userRow定义为

type userRow struct {
    UserId        string
    FirstName     string
    LastName      string
}

To solve the issue I had, I added a db tag to the struct: 为了解决我遇到的问题,我在结构中添加了一个db标记:

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

Hope this can help someone in the furute. 希望这可以帮助一些人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM