Golang 将 form-urlencoded 序列化为对象

Posted

技术标签:

【中文标题】Golang 将 form-urlencoded 序列化为对象【英文标题】:Golang serialize form-urlencoded to object 【发布时间】:2022-01-15 12:19:57 【问题描述】:

我发出了一个发布请求,我将数据作为 JSON 发送,这段代码在数据库中创建了一个新行。

json.NewDecoder(r.Body).Decode(&user)
DB.Create(&user)
json.NewEncoder(w).Encode(user)

但是解析表单数据显示这个错误 我想这就是我读取每个单独值的方式

for key, value := range r.PostForm 
        fmt.Printf("Key:%s, Value:%s\n", key, value)

我的模型是这样的

type User struct 
    gorm.Model
    FirstName string `json:"firstname"`
    LastName  string `json:"lastname"`
    Email     string `json:"email"`

如何将其转换为用户并插入数据库?

【问题讨论】:

json.NewDecoder(r.Body).Decode(&user) 是解码 JSON 请求正文的正确方法。那失败了吗?如果确实失败了,那么 Decode 返回的错误是什么? 确实如此,我不想接受 JSON 请求正文,我正在以 application/x-www-form-urlencoded 的身份通过邮递员发送请求 u.FirstName = r.FormValue("firstname") 等等。 需要解析一个 URL 编码的表单给用户 ***.com/questions/44052311/… 【参考方案1】:

另一种方法(有点过度设计,最好使用r.FormValue),如果您已经知道数据、类型等,则无需再次键入字段,例如r.FormValue("firstname")等。

func handleUser(w http.ResponseWriter, r *http.Request) 
    user := User
    userType := reflect.TypeOf(user)
    for i := 0; i < userType.NumField(); i++ 
        // Get the JSON tag of the field, use it for the r.FormValue
        f := userType.Field(i).Tag.Get("json")
        if f != "" 
            reflect.ValueOf(&user).Elem().FieldByName(
                userType.Field(i).Name).SetString(r.FormValue(f))
        
    
    // DB.Create(&user) need a reference to DB here.
    json.NewEncoder(w).Encode(user)

注意:这只是一个适用于字符串字段的示例,否则可能会因为调用SetString 而引起恐慌。此外,一个字段可能不存在,并且在尝试在FieldByName(... 中访问它时可能会出现恐慌,但我认为您的问题是针对这个不必键入每个字段的方向,因此将其作为示例。

正如 Cerise Limón 指出的那样,正确的做法是

func handleUser(w http.ResponseWriter, r *http.Request) 
    user := User
    user.FirstName = r.FormValue("firstname")
    user.LastName = r.FormValue("lastname")
    user.Email = r.FormValue("email")
    // DB.Create(&user) need a reference to DB here.
    json.NewEncoder(w).Encode(user)

请注意,如果您在多个地方执行此操作,您还可以添加一个使用表单填充用户的方法,例如

func (u *User) setFormData(r *http.Request) 
    u.FirstName = r.FormValue("firstname")
    u.LastName = r.FormValue("lastname")
    u.Email = r.FormValue("email")

然后像这样使用它

func handleUser(w http.ResponseWriter, r *http.Request) 
    user := User
    user.setFormData(r)
    // DB.Create(&user)
    json.NewEncoder(w).Encode(user)

【讨论】:

以上是关于Golang 将 form-urlencoded 序列化为对象的主要内容,如果未能解决你的问题,请参考以下文章

javascript 简单的AJAX js数据发送; form-urlencoded格式

说说$POST $HTTP_RAW_POST_DATAphp://input三者之间的区别

golang 将接口值与#golang中的nil进行比较

使用 Golang 将嵌套数据插入 BigQuery

Golang 将视频按照时间维度剪切 | Golang工具

golang GoLang使用AES加密将字符串加密到base64,反之亦然。