2014-04-26 49 views
2

我有一个这样的处理程序:Go lang解码io.read JSON v.s.解组给出不同的结果

type Location struct { 
    Lat float32 `json:"lat"` 
    Lon float32 `json:"lon"` 
} 



func handleJSONLocation(res http.ResponseWriter, req *http.Request) {  
    b := new(Location) 
    var bb Location; 
    buf := new(bytes.Buffer) 
    buf.ReadFrom(req.Body) 

    json.Unmarshal(buf.Bytes(), &bb) 
    json.NewDecoder(req.Body).Decode(b) 

    log.Printf("%s %f,%f %f,%f", buf.String(), b.Lat, b.Lon, bb.Lat, bb.Lon); 

    data, _ := json.Marshal("{'location':'saved'}") 
    res.Header().Set("Content-Type", "application/json; charset=utf-8") 
    res.Write(data) 
} 

我得到

2014/04/25 22:05:55 {"lat":42.9635013,"lon":-81.22387210000001} 0.000000,0.000000 42.963501,-81.223869 

为什么不b对象获取解码成?

问候

回答

8

当运行下面的代码,所述HTTP请求的整个主体被读入buf

buf := new(bytes.Buffer) 
buf.ReadFrom(req.Body) 

此时,从req.Body进一步读取将导致EOF错误。所以,当你试图解码成b,你得到一个错误,如果你的东西,如检查返回值这将是明显的:

if err := json.NewDecoder(req.Body).Decode(b); err != nil { 
    log.Println("Could not decode body:", err) 
} 

这也将是明智的检查对其他函数调用错误你做。

由于您已经将请求正文读入内存缓冲区,您可以创建一个新的bytes.Buffer以传递给期望io.Reader(如json.NewDecoder)的API。

+5

如果使用'ioutil.ReadAll(resp.Body)'调试并且之后进行json解码,那么也会出现EOF错误。 –

+2

你的评论肯定为我节省了一些时间:) – Neal