解决golang读取http的body时遇到的坑
当服务端对http的body进行解析到map[string]interface{}时,会出现cli传递的是int类型,而服务端只能断言成float64,而不能将接收到的本该是int类型的直接断言为int
cli
funcmain(){ url:="http://127.0.0.1:8335/api/v2/submit" myReq:=struct{ ProductIdint`json:"product_id"` Mobilestring`json:"mobile"` Contentstring`json:"content"` Gradefloat64`form:"grade"json:"grade"` Imagestring`form:"image"json:"image"` Longitudefloat64`json:"longitude"` Latitudefloat64`json:"latitude"` }{ ProductId:219, Mobile:"15911111111", Content:"这个软件LOGO真丑", Image:"www.picture.com;www.picture.com", Longitude:106.3037109375, Latitude:38.5137882595, Grade:9.9, } reqByte,err:=json.Marshal(myReq) req,err:=http.NewRequest("POST",url,bytes.NewReader(reqByte)) iferr!=nil{ return } //设置请求头 req.Header.Add("Content-Type","application/json") cli:=http.Client{ Timeout:45*time.Second, } resp,err:=cli.Do(req) iferr!=nil{ return } out,err:=ioutil.ReadAll(resp.Body) iferr!=nil{ return } fmt.Println(string(out)) }
server
funcSubmitV2(c*gin.Context){ resp:=&dto.Response{} obj:=make(map[string]interface{}) varbuf[]byte varerrerror buf,err=ioutil.ReadAll(c.Request.Body) iferr!=nil{ return } err=json.Unmarshal(buf,&obj) iferr!=nil{ return } fmt.Println("product_id:",reflect.TypeOf(obj["product_id"])) fmt.Println("image:",reflect.TypeOf(obj["image"])) fmt.Println(obj) productId:=obj["product_id"].(float64) //注意,这里断言成int类型会出错 c.Request.Body=ioutil.NopCloser(bytes.NewBuffer(buf)) if!checkProduct(int(productId)){ resp.Code=-1 resp.Message="xxxxxx" c.JSON(http.StatusOK,resp) return } url:=config.Optional.OpinionHost+"/api/v1/submit" err=http_utils.PostAndUnmarshal(url,c.Request.Body,nil,resp) iferr!=nil{ logrus.WithError(err).Errorln("Submit:error") resp.Code=-1 resp.Message="Submit" } c.JSON(http.StatusOK,resp) }
打印类型,发现product_id是float64类型
原因:json中的数字类型没有对应int,解析出来都是float64
补充:GolangWeb获取http请求报文主体body的内容
示例代码:
packagemain import( "fmt" "net/http" ) funcheaderBody(rwhttp.ResponseWriter,r*http.Request){ //获取请求报文的内容长度 len:=r.ContentLength //新建一个字节切片,长度与请求报文的内容长度相同 body:=make([]byte,len) //读取r的请求主体,并将具体内容读入body中 r.Body.Read(body) //将字节切片内容写入相应报文 fmt.Fprintln(rw,body) } funcmain(){ server:=http.Server{ Addr:"127.0.0.1:http", } http.HandleFunc("/",headerBody) server.ListenAndServe() }
注意:
1.get请求不包含报文主体。
2.post请求不包含报文主体。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。