go-json-rest: JSON负载为空

huangapple go评论102阅读模式
英文:

go-json-rest: JSON payload is empty

问题

我正在尝试使用go-json-rest创建RESTful API。

我有以下模型结构:

type Todo struct {
    id   int
    name string
}

我试图发送一个POST请求来创建一个Todo类型的对象:

func CreateTodo(w rest.ResponseWriter, r *rest.Request) {
    body, _ := ioutil.ReadAll(r.Body)
    log.Println("body content is: ", string(body)) // 这里我可以看到 { "name": "test1" }
    var todo Todo = Todo{}
    err := r.DecodeJsonPayload(&todo) // 这里的错误显示JSON负载为空
    defer r.Body.Close()

    if err != nil {
        log.Println("error in parsing json")
        rest.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    if todo.name == "" {
        rest.Error(w, "todo name is required", 400)
        return
    }
    lock.Lock()

    var nextId int = len(todos)
    // todos[nextId] = todo
    todo.id = nextId // 设置其id
    todos = append(todos, todo)
    log.Println("num of todos: ", len(todos))
    lock.Unlock()

    w.WriteJson(&todo)
}

然而,在POSTMAN客户端的控制台中,错误显示为:

{
  "Error": "JSON payload is empty"
}

我想知道可能出了什么问题。谢谢。

编辑:
这个问题不应该被视为重复问题,因为我甚至没有尝试使用json包来进行JSON对象的编组/解组。相反,我正在使用rest.Request对象(内置于go-json-rest中)来解码从客户端发送的JSON参数。

经过深入挖掘和搜索,我发现下面的答案解决了我的问题:

body, _ := ioutil.ReadAll(r.Body)会消耗请求体中的所有内容。因此,删除这行代码后,JSON解析就可以正常工作!

英文:

I'm trying to use go-json-rest to create RESTful APIs

I have this model struct:

type Todo struct {
	id   int
	name string
}

And I am trying to do a POST request to create an object of Todo type:

func CreateTodo(w rest.ResponseWriter, r *rest.Request) {

	body, _ := ioutil.ReadAll(r.Body)
    log.Println("body content is: ", string(body)) // here I can see {"name": "test1"}
    var todo Todo = Todo{}
    err := r.DecodeJsonPayload(&todo) // here the error shows JSON payload is empty
	defer r.Body.Close()

	if err != nil {
		log.Println("error in parsing json")
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	if todo.name == "" {
		rest.Error(w, "todo name is required", 400)
		return
	}
	lock.Lock()

	var nextId int = len(todos)
	//	todos[nextId] = todo
	todo.id = nextId // set its id
	todos = append(todos, todo)
	log.Println("num of todos: ", len(todos))
	lock.Unlock()

	w.WriteJson(&todo)
}

However, in the console of the POSTMAN client, the error shows:

{
  "Error": "JSON payload is empty"
}

I was wondering where might go wrong. Thanks

Edit:
This should not be considered a duplicate question, because I am not even trying to use the json package to do marshalling/unmarshalling of JSON object. Instead I am using the rest.Request object (built in go-json-rest) to decode the json parameters as posted from client.

After much digging and search on this problem I found this answer below resolved my issue:

> body, _ := ioutil.ReadAll(r.Body) will consume everything from the
> request body. So after removing this line, the json parsing works!

答案1

得分: 0

我之前只是在不真正理解ioutil.ReadAll()对请求体的操作时,做了一个愚蠢的事情,即在解码JSON参数之前执行了body, _ := ioutil.ReadAll(r.Body)

正如我在编辑后的帖子中引用的那样,ioutil.ReadAll()会消耗请求体中的所有内容,不会留下任何内容供JSON解码器解析。在删除body, _ := ioutil.ReadAll(r.Body)这一行之后,JSON解析按预期工作。

英文:

I was just being silly doing body, _ := ioutil.ReadAll(r.Body) before decoding the JSON parameters without really understanding what ioutil.ReadAll() does to the request body.

As I quoted above in the edited post, ioutil.ReadAll() consumes everything in the request body, leaving nothing for the json decoder to parse. After removing the line body, _ := ioutil.ReadAll(r.Body), the json parsing works as expected.

huangapple
  • 本文由 发表于 2017年1月2日 02:04:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/41417718.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定