如何在JSON(Go)中处理超出范围的索引

时间:2014-12-11 02:13:20

标签: json go

我正在开发一个Web服务,其中一部分我阅读了Request.Body并尝试解组它。

if err := json.NewDecoder(body).Decode(r); err !=nil{
    log.Error(err)
    return err
}

问题是,有时客户端发送一个空的身体,我感到恐慌runtime error: index out of range goroutine 7 [running]:  我该如何缓解这种情况?

3 个答案:

答案 0 :(得分:0)

我正在分解你的代码:

NewDecoder: -

func NewDecoder(r io.Reader) *Decoder
  

NewDecoder返回一个从r读取的新解码器。解码器   引入了自己的缓冲,可以读取超出JSON的r数据   要求的价值。

因此NewDecoder只从r读取数据。它不在乎,r是空的......

Decode: -

func (dec *Decoder) Decode(v interface{}) error
  

Decode从其输入读取下一个JSON编码值并存储它   在v。

指向的值中      

有关将JSON转换为Go值的详细信息,请参阅Unmarshal的文档。

要将JSON解组为接口值,Unmarshal会将其中一个存储在接口值中:

bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
  

如果JSON值不适合给定的目标类型,或者如果a   JSON号溢出目标类型,Unmarshal跳过该字段和   尽可能地完成解组。如果没有更严重的错误   遇到,Unmarshal返回一个UnmarshalTypeError描述   最早的这种错误。

     

JSON null值解组为接口,map,指针或   通过将Go值设置为nil进行切片。因为经常使用null   JSON表示“不存在”,将JSON null解组为任何其他Go   type对值没有影响并且不会产生错误。

阅读上面的陈述,很明显没有机会,我们得到运行时恐慌错误。我正在尝试使用sample code来重现此错误。可能来自JSON包或您自己的代码中的错误。

答案 1 :(得分:-1)

var dummy []byte
dummy = make([]byte, 10)
size, _ := body.Read(dummy)
if size > 0 {
  if err := json.NewDecoder(body).Decode(r); err != nil {
          log.Error(err)
          return err
} 
fmt.Fprintf(w, "%s", "Json cannot be empty")// where w is http.ResponseWriter

答案 2 :(得分:-3)

您只想在尝试解组之前确保Request.Body不为空。

if body != "" || body != nil || len(body) > 0 {
     if err := json.NewDecoder(body).Decode(r); err != nil {
          log.Error(err)
          return err
     }
}

或者,如果您要准备任何内容,请使用this answergolang playground)中的IsJSON函数检查正文是否为有效JSON,然后再尝试将其解码为JSON。