我试图获取一个HTTP请求主体,它是一个json对象,并将其解码为我已定义的Go结构.
结构的两个字段是time.Time
类型.虽然只有一个这样的类型字段,但一切正常.
如果我time.Time
在go结构中有多个类型字段,我无法解码它并得到错误:
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":nu??ll,"email":null,"address":null,"city":null,"country":null,"language":null,"lastlo??gintimestamp":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)
}
Run Code Online (Sandbox Code Playgroud)
好.这是一个可重现的示例,演示了您所看到的错误.
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)
}
}
Run Code Online (Sandbox Code Playgroud)
您看到的错误与多个时间戳无关.这就是为什么显示输入对于调试此类情况至关重要的原因,以及为什么您应该返回并更改您的问题以将示例requestBody
作为问题内容的一部分包含在内.否则,它变得非常难以猜测你在做什么.
发生了什么事情是null
由JSON unmarshaller处理的time.Time
.该文件对了time.time的解组说:UnmarshalJSON实现json.Unmarshaler接口.预计时间是RFC 3339格式的带引号的字符串.
null
不是这样的值:在这种情况下,解码器不会尝试为时间戳构造"零"值.
你想要做的是改变的类型SignupTimestamp
,从time.Time
到*time.Time
,这样的null
值可以明确地表示为nil
指针.
这是一个示例:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1790 次 |
最近记录: |