Go web中修改操作需要注意的一点

不仅是Gin框架,曾经在http库中也遇到过类似的问题,所以进行详细的分析!

定位到前端代码:bubble_frontend/TodoList.vue at master · Q1mi/bubble_frontend (github.com)

handleEdit(index, row) {
  let messageSuffix = row.status ? " 置为未完成" : " 置为已完成";
  this.axios
    .put("/v1/todo/" + row.id, {
      status: !row.status
    })
    .then(() => {
      this.tableData[index].status = !row.status;
      this.$message({
        showClose: true,
        duration: 1500,
        message: `<${row.title}> ${messageSuffix}`,
        type: "success"
      });
    });
},

status为bool类型。

可以清楚的看到,前端向/v1/todo/:id发送了PUT请求,并且发送了!status

同时可以在服务器端,截取到完整的请求信息来验证,这里参考了:Gin 框架优雅的获取所有的请求参数 | 热浪编程 (pudongping.com)

pScQLuj.png

// 修改某一个待办事项
		v1Group.PUT("/todo/:id", func(c *gin.Context) {
			id, ok := c.Params.Get("id")
			if !ok {
				c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
				return
			}
			var todo Todo
			if err = DB.Where("id=?", id).First(&todo).Error; err != nil {
				c.JSON(http.StatusOK, gin.H{"error": err.Error()})
				return
			}
      // 此时的todo是从数据库取出的:{ID:1 Title:吃饭 Status:false}
			c.BindJSON(&todo) // 这一步,c中有前端传来的{"status":true};
			if err = DB.Save(&todo).Error; err != nil {
				c.JSON(http.StatusOK, gin.H{"error": err.Error()})
			} else {
				c.JSON(http.StatusOK, todo)
			}
		})

疑问{ID:1 Title:吃饭 Status:false} 经过 c.BindJSON(&todo) 之后,就修改为 {ID:1 Title:吃饭 Status:true}

  • c中只有前端传来的{"status":true},Todo结构体的部分成员变量。

经过对c.BindJSON(&todo)的源码分析,最终发现核心起作用的是关于json.Decoder,并对其做出如下模拟:

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func main() {
	str := `{"age":18}`                   // 模拟前端传来的某条参数;
	person := Person{Name: "老六", Age: 27} // 模拟数据库中已有的记录;
	err := json.NewDecoder(strings.NewReader(str)).Decode(&person)
	if err == nil {
		fmt.Printf("解码结果: %+v", person)
	} // 解码结果: {Name:老六 Age:18}
}

总结:对于Go语言常见的库,应该扎实掌握!

posted @ 2023-02-06 13:15  KpHang  阅读(93)  评论(0编辑  收藏  举报