【问题标题】:Read request body two times in Golang [duplicate]在Golang中两次读取请求正文[重复]
【发布时间】:2018-11-18 16:45:38
【问题描述】:
type ValidationModel struct {
    Name     string `json:"name" valid:"alpha,required~Name is required"`
    Email    string `json:"email" valid:"email~Enter a valid email.,required~Email is required."`
    Password string `json:"password" valid:"required~Password is required"`
}

validationModel := ValidationModel{}

json.NewDecoder(r.Body).Decode(&validationModel)

_, err := govalidator.ValidateStruct(validationModel)

首先我使用 govalidator 验证请求正文。

type UserModel struct {
    ID           bson.ObjectId `json:"_id" bson:"_id"`
    Name         string        `json:"name" bson:"name"`
    Email        string        `json:"email" bson:"email"`
    Password     string        `json:"password,omitempty" bson:"-"`
    PasswordHash string        `json:"-" bson:"passwordHash"`
    Salt         string        `json:"-" bson:"salt"`
    Token        string        `json:"token,omitempty" bson:"-"`
}


user := models.UserModel{}
json.NewDecoder(r.Body).Decode(&user)

fmt.Println(user)

在验证请求后,我再次将请求正文解码为用户结构,但请求正文已使用验证模型读取一次,因此当我尝试再次将其解码为用户时,它没有给我任何值。

我可以在这里想到两个解决方案:

  1. 将请求正文存储在一个单独的变量中,并使用该变量两次。

  2. 在用户中复制 validationModel 值。

但我对实施这些方法以及最好遵循哪种方法一无所知。或者有没有其他可以实现的解决方案?

提前致谢。

【问题讨论】:

  • 在您的情况下,您应该重新考虑不阅读正文两次。在解码后验证解码数据,而不是解码两次,效率更高(尤其是如果你有大身体)。
  • @Flimzy 你能解释一下如何重构代码吗?我还有另一种方法,我可以将一个结构的数据复制到另一个结构中。我该怎么做?
  • 一般来说:不要有单独的“ValidationModel”——而是验证UserModel

标签: json go request


【解决方案1】:

使用ioutil.ReadAll()可以轻松存储数据:

data, err := ioutil.ReadAll(r.Body)

如果您需要将data 作为io.Reader 返回(r.Body 就是这样),那么您可以使用bytes.NewReader()

reader := bytes.NewReader(data)

实际上,r.Bodyio.ReadCloser,因此如果您需要,可以将 ioutil.NopCloser()bytes.NewReader() 结合使用:

reader := ioutil.NopCloser(bytes.NewReader(data))

【讨论】:

猜你喜欢
  • 2017-08-18
  • 2018-04-07
  • 2015-10-02
  • 2014-10-29
  • 2021-10-21
  • 2015-12-22
  • 2020-10-25
  • 1970-01-01
  • 2016-04-20
相关资源
最近更新 更多