Golang json Unmarshal “JSON 输入意外结束”

Posted

技术标签:

【中文标题】Golang json Unmarshal “JSON 输入意外结束”【英文标题】:Golang json Unmarshal "unexpected end of JSON input" 【发布时间】:2015-03-15 16:04:36 【问题描述】:

我正在编写一些代码来解析来自 HTTP 响应的 JSON 数据。我的代码如下所示:

type ResultStruct struct 
    result []map[string]string


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

respBytes 变量中的 json 如下所示:


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

但是,err 不是零。当我打印出来时,上面写着unexpected end of JSON input。这是什么原因造成的? JSON似乎有效。这个错误是否与我的自定义结构有关?

提前致谢!

【问题讨论】:

respBytes 的阅读方式如何? 另外,请注意小写字母表示私有可见性。您希望ResultStruct 中的字段名称大写:否则json 解码器不允许接触该字段。请参阅:play.golang.org/p/bATT5uMPRT 以获取似乎有效的示例。因此,我们需要更多信息来了解您的错误是什么:所述问题不足以说明问题。 @dyoo respBytes 只是一个字节数组(我接受响应,进行一些处理并提取正文)。我还将ResultStruct 中的结果字段大写。您的 Go Playground 示例采用了我收到的 JSON 并正确处理它,所以我的代码肯定有其他问题...感谢您的帮助! 【参考方案1】:

unexpected end of JSON input 是 JSON 输入中a syntax error 的结果(可能缺少"])。该错误与您要解码的值的类型无关。

我使用示例 JSON 输入 on the playground 运行代码。它运行没有错误。

代码不会解码任何内容,因为result 字段未导出。如果导出结果字段:

type ResultStruct struct 
   Result []map[string]string

然后输入被解码,如playground example所示。

我怀疑您没有阅读应用程序中的整个响应正文。我建议使用以下方法解码 JSON 输入:

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

解码器直接从响应正文中读取。

【讨论】:

我怀疑除了@3of3 所说的之外,您还尝试解析没有最后一个“”字符的 JSON。 这是有道理的,但是我打印出 JSON 并通过在线验证器以及 @dyoo 的 Go 游乐场示例运行它,它成功了。我必须得出结论,这个错误是由于我的代码的另一部分存在问题。谢谢!【参考方案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”,则代码有效。

【讨论】:

你刚刚拯救了我的一天。我不会想到会是这个问题。谢谢! 它给出了 JSON 输入意外结束 错误【参考方案3】:

这里不是这样;但是,如果您从文件加载 json 时遇到此错误,则如果缓冲区的字节切片未初始化为文件的字节大小,则会发生此错误。 [当你像我一样是新手时,会发生这种情况! ] 因为这是我得到的第一个搜索结果,所以仍然需要一些挖掘才能弄清楚。在这个用例中,错误有点误导。

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)

【讨论】:

以上是关于Golang json Unmarshal “JSON 输入意外结束”的主要内容,如果未能解决你的问题,请参考以下文章

Golang json Unmarshal “JSON 输入意外结束”

golang里的json marshal && unmarshal

markdown Golang json processing.md中的marshal和unmarshal问题

golang Marshal / Unmarshal将不同的JSON对象转换为Go结构

golang 将json映射到GO中的struct,用于直接编组,unmarshal

golang Marshal和Unmarshal处理json数据