Golaong invalid character ‘\x00‘ after top-level value

Golaong invalid character ‘\x00’ after top-level value

1 概述

当我们无法无法判断需要创建的字节切片A的长度的时候,通常会创建一个较大长度的空字节切片B来接收未知长度的字节,当使用json.Unmarshal解析字节的时候,就会出现 panic invalid character ‘\x00’ after top-level value 的错误,这是因为B切片的长度实际大于A所需的长度,Json读取到nil的时候,会停止继续读取, 造成多出一个\x00,而json无法解析\x00

错误日志

2020/07/31 13:44:14 [Recovery] 2020/07/31 - 13:44:14 panic recovered:
POST /price HTTP/1.1
Host: localhost:8080
Accept: */*
Accept-Encoding: gzip, deflate, br
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 133
Content-Type: application/json
Postman-Token: 97f9e99a-4e28-4d3b-a241-372efbcf4ee4
User-Agent: PostmanRuntime/7.26.2


invalid character '\x00' after top-level value
D:/Library/Code/Projects/cloud-price/main.go:23 (0xa9a0ee)
	main.func1: panic(err)
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0xa7a91f)
	(*Context).Next: c.handlers[c.index](c)
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:83 (0xa96ca7)
	RecoveryWithWriter.func1: c.Next()
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0xa7a91f)
	(*Context).Next: c.handlers[c.index](c)
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:241 (0xa9578b)
	LoggerWithConfig.func1: c.Next()
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0xa7a91f)
	(*Context).Next: c.handlers[c.index](c)
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:409 (0xa878bb)
	(*Engine).handleHTTPRequest: c.Next()
C:/Users/Mist/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:367 (0xa8736c)
	(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
D:/Go/src/net/http/server.go:2774 (0x7be64c)
	serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
D:/Go/src/net/http/server.go:1878 (0x7b8d09)
	(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
D:/Go/src/runtime/asm_amd64.s:1337 (0x45f4e0)
	goexit: BYTE	$0x90	// NOP

2 解决方法

在B接收A后,可用A的长度截取切片,在传递至 json.Unmarshal 解析

// 创建一个容量和长度都是2048的字节切片
buffer := make([]byte, 2048)
...
// Read 会返回 Body 字节的长度length,然后使用length截取切片 buffer[:length],再解析
json.Unmarshal(buffer[:length], &request)

3 code

这里以gin的post请求为例

package main

import (
	"fmt"
	"encoding/json"
	"github.com/gin-gonic/gin"
)
	


func main(){
	fmt.Println("Hello Rain")
	route := gin.Default()

	route.POST("/price", func(c * gin.Context){
        // 创建一个容量和长度都是2048的字节切片
		buffer := make([]byte, 2048)
		var request struct{
            Action string
            Component string
            Params interface{}
            RequestID string
            Version int64
        }
        // Read 会返回 Body 字节的长度length,然后使用length截取切片 buffer[:length],再解析
		length,_ := c.Request.Body.Read(buffer)
		if err := json.Unmarshal(buffer[:length], &request); err!=nil{
			panic(err)
		}

		fmt.Println("body: ", request)

		c.JSON(200, gin.H{
			"author": "rain",
		})
	})

	route.GET("/file")

	route.Run()
}

猜你喜欢

转载自blog.csdn.net/qq_40601372/article/details/107712820