英文:
Custom UnmarshalJSON for custom time format returning this {0 63082400645 <nil>} instead of time with ShouldBindJSON from Gin gonic
问题
我有这个类型和处理程序
type Bday time.Time
func (mt *Bday) UnmarshalJSON(bs []byte) (err error) {
var t time.Time
layout := "2006-01-02T15:04:05Z0700" // RFC3339
s := strings.Trim(string(bs), `"`)
t, err = time.Parse(layout, s)
if err != nil {
return err
}
*mt = Bday(t)
return
}
func (mt Bday) MarshalJSON() ([]byte, error) {
timestamp := time.Time(mt)
return json.Marshal(timestamp)
}
type LoginHandler struct {
db *gorm.DB
}
func (l *LoginHandler) Signup(c *gin.Context) {
// 验证姓名、姓氏、电子邮件、密码、性别、出生日期
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), 8)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
user.Password = string(hashedPassword)
fmt.Println("User", user)
// 保存到数据库
l.db.Debug().Model(&models.User{}).Create(&user)
// 返回代码201
c.JSON(http.StatusCreated, gin.H{"message": "用户创建成功!"})
}
这是用户
type User struct {
Password string `json:"password"`
Email string `json:"email"`
Name string `json:"name"`
LastName string `json:"last_name"`
Bday Bday `json:"bday"`
Gender string `json:"gender"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt time.Time `json:"deleted_at"`
}
当我在处理程序中打印用户时,我得到了Bday字段的以下输出
{0 63082400645 <nil>}
这是完整的println
User {$2a$08$uTE7Llc6YM2owu.D6UWqpOcOVFHRFRrSxbkxWV4ecR72G6kK5/SNq d.n.m@gmail.com
Antonio Magalhães {0 63082400645 <nil>} M 0001-01-01 00:00:00 +0000 UTC 0001-01-01
00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC}
我期望的是Bday是一个类似日期的东西
2001-01-01 00:00:00 +0000 UTC
有人可以帮我理解这个吗?
英文:
I have this type and handler
type Bday time.Time
func (mt *Bday) UnmarshalJSON(bs []byte) (err error) {
var t time.Time
layout := "2006-01-02T15:04:05Z0700" // RFC3339
s := strings.Trim(string(bs), `"`)
t, err = time.Parse(layout, s)
if err != nil {
return err
}
*mt = Bday(t)
return
}
func (mt Bday) MarshalJSON() ([]byte, error) {
timestamp := time.Time(mt)
return json.Marshal(timestamp)
}
type LoginHandler struct {
db *gorm.DB
}
func (l *LoginHandler) Signup(c *gin.Context) {
// Verify name, lastName, email, password, gender, birthDate
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), 8)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
user.Password = string(hashedPassword)
fmt.Println("User", user)
// Save to db
l.db.Debug().Model(&models.User{}).Create(&user)
// Return code 201
c.JSON(http.StatusCreated, gin.H{"message": "User created successfully!"})
}
This is the User
type User struct {
Password string `json:"password"`
Email string `json:"email"`
Name string `json:"name"`
LastName string `json:"last_name"`
Bday Bday `json:"bday"`
Gender string `json:"gender"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt time.Time `json:"deleted_at"`
}
When I print User in the handler I get this for the Bday field
{0 63082400645 <nil>}
This is the full println
User {$2a$08$uTE7Llc6YM2owu.D6UWqpOcOVFHRFRrSxbkxWV4ecR72G6kK5/SNq d.n.m@gmail.com
Antonio Magalhães {0 63082400645 <nil>} M 0001-01-01 00:00:00 +0000 UTC 0001-01-01
00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC}
What I expected whas that Bday were something like a date
2001-01-01 00:00:00 +0000 UTC
Can somebody help me understand this?
答案1
得分: 1
你自定义的类型 Bday
既不满足 Formatter
接口,也不满足 Stringer
接口,因此会以复合结构的形式打印出来(底层 time.Time
结构的字段会逐个打印出来)。
一个简单的解决方法是实现一个 String()
方法,例如委托给 MarshalJSON
:
func (mt Bday) String() string {
b, _ := mt.MarshalJSON()
return string(b)
}
有关 fmt.Println
如何工作的更多详细信息,请参考 fmt
包 的文档。
英文:
Your custom type Bday
satisfies neither Formatter
nor Stringer
interface, and thus gets printed as a compound struct (the fields of the underlying time.Time
struct are printed individually).
An easy fix would be to implement a String()
method, for example delegating to MarshalJSON
:
func (mt Bday) String() string {
b, _ := mt.MarshalJSON()
return string(b)
}
For more details on how fmt.Println
works refer to fmt
package documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论