我正在开发一个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]:
我该如何缓解这种情况?
答案 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 answer(golang playground)中的IsJSON
函数检查正文是否为有效JSON,然后再尝试将其解码为JSON。