我正在尝试获取一个HTTP请求主体,它是一个json对象并将其解码为我定义的Go结构。
结构的两个字段是time.Time
类型。虽然只有一个这样的类型字段,但一切正常。
如果我在go结构中有多个time.Time
类型的字段,我无法对其进行解码并收到错误:
2014/11/01 01:07:04 parsing time "null" as ""2006-01-02T15:04:05Z07:00"": cannot parse "null" as """
问题在于解码线。尽管我的调试努力,我本可以取得有意义的结果。这个问题似乎很奇怪,实际上不应该这样。
我在这里缺少什么?
func register(w http.ResponseWriter, r *http.Request){
//Read Request Body JSON Into Go Types
var requestBody = []byte(`{"username":"qwewwwqweqwe","password":"can","usertype":"student","firstname":"","midname":null,"surname":null,"signuptimestamp":null,"userstatus":null,"phone":null,"email":null,"address":null,"city":null,"country":null,"language":null,"lastlogintimestamp":null}`)
type RegisterStructure struct {
Id int `json:"id"`
Timestamp time.Time `json:"timestamp,omitemty"`
SignupTimestamp time.Time `json:"signuptimestamp,omitempty"`
Username string `json:"username"`
Password string `json:"password"`
UserType string `json:"usertype"`
FirstName string `json:"firstname"`
Midname string `json:"midname"`
Surname string `json:"surname"`
UserStatus string `json:"userstatus"`
Phone string `json:"phone"`
Email string `json:"email"`
Address string `json:"address"`
City string `json:"city"`
Country string `json:"country"`
Language string `json:"language"`
//LastLoginTimestamp time.Time `json:"lastlogintimestamp,omitempty"`
}
var registerInstance RegisterStructure
var now = time.Now()
fmt.Printf("now is %v", now)
fmt.Println()
fmt.Printf("1 registerInstance after inited here is %v", registerInstance)
fmt.Println()
registerInstance = RegisterStructure{Timestamp: now, SignupTimestamp: now,}
fmt.Printf("registerInstance after set to var now here is %v", registerInstance)
fmt.Println()
dec := json.NewDecoder(bytes.NewReader(requestBody))
err = dec.Decode(®isterInstance)
if err != nil {
fmt.Printf("error happens here.")
log.Fatal(err)
}
答案 0 :(得分:5)
确定。这是一个reproducible example,用于演示您所看到的错误。
package main
import (
"encoding/json"
"fmt"
"bytes"
"time"
)
type RegisterStructure struct {
SignupTimestamp time.Time `json:"signuptimestamp,omitempty"`
}
func main() {
requestBody := []byte(`{"signuptimestamp" : null}`)
dec := json.NewDecoder(bytes.NewReader(requestBody))
registerInstance := RegisterStructure{}
err := dec.Decode(®isterInstance)
if err != nil {
fmt.Println(err)
}
}
您看到的错误与多个时间戳无关。这就是为什么显示输入对于调试此类情况至关重要的原因,以及为什么您应该返回并更改您的问题以包含示例requestBody
作为问题内容的一部分。否则,很难猜到你正在做什么。
正在发生的事情是null
的JSON unmarshaller没有处理time.Time
。 documentation为time.Time的unmarshaller说: UnmarshalJSON实现了json.Unmarshaler接口。预计时间是RFC 3339格式的带引号的字符串。
null
不是这样的值:在这种情况下,解码器不会尝试为时间戳构造“零”值。
您要做的是将SignupTimestamp
的类型从time.Time
更改为*time.Time
,以便null
值可以明确表示为nil
}指针。
以下是example来演示:
package main
import (
"bytes"
"encoding/json"
"fmt"
"time"
)
type RegisterStructure struct {
SignupTimestamp *time.Time `json:"signuptimestamp,omitempty"`
}
func main() {
requestBodies := []string{
`{"signuptimestamp" : "1985-04-12T23:20:50.52Z"}`,
`{"signuptimestamp" : null}`,
}
for _, requestBody := range requestBodies {
dec := json.NewDecoder(bytes.NewReader([]byte(requestBody)))
registerInstance := RegisterStructure{}
err := dec.Decode(®isterInstance)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%#v\n", registerInstance)
}
}