Go net/http
handler依自訂日期時間格式接收POST請求的JSON中的日期時間字串並轉為time.Time
範例。
範例環境:
- Go 1.17
Client發送請求的JSON字串如下。日期時間格式為yyyy-MM-dd
格式。
{
"id": 1,
"name": "john",
"age": 33,
"createdDate": "2022-01-19"
}
由於time.Time
接收的字串格式必須是RFC3339格式(e.g. yyyy-MM-ddThh:mm:ssZ
),所以下面自訂接收的格式為yyyy-MM-dd
。
一 - 實作 json.Unmarshaler
, json.Marshaler
Employee
為JSON字串要轉成的struct。定義type Date
為time.Time
並實作json.Unmarshaler
及json.Marshaler
介面。
實作Unmarshaler.UnmarshalJSON()
自訂json轉換為物件的邏輯;
實作Marshaler.MarshalJSON()
自訂轉換物件為json的邏輯。
main.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
type Date time.Time
var df = "2006-01-02"
func (d *Date) UnmarshalJSON(b []byte) error {
s := strings.Trim(string(b), "\"")
t, err := time.Parse(df, s)
if err != nil {
return err
}
*d = Date(t)
return nil
}
func (d Date) MarshalJSON() ([]byte, error) {
t := time.Time(d)
s := t.Format(df)
return json.Marshal(s)
}
type Employee struct {
Id int
Name string
Age int
CreatedDate Date
}
func main() {
http.HandleFunc("/employee", func(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
var emp Employee
if err := json.NewDecoder(r.Body).Decode(&emp); err != nil {
panic(err)
}
fmt.Println(time.Time(emp.CreatedDate)) // 2021-01-19 00:00:00 +0000 UTC
json.NewEncoder(rw).Encode(emp)
default:
http.Error(rw, "Method not allowed", http.StatusMethodNotAllowed)
}
})
http.ListenAndServe(":8080", nil)
}
測試
啟動應用程式後在命令列以cURL發出以下請求。
$ curl -X POST "http://localhost:8080/employee" -H 'content-type: application/json' -d '{"id": 1, "name": "john", "age": 33, "createdDate": "2021-01-19"}'
在console印出以下。
2021-01-19 00:00:00 +0000 UTC
回應結果如下:
{"Id":1,"Name":"john","Age":33,"CreatedDate":"2021-01-19"}
二 - 實作 encoding.TextMarshaler
, encoding.UnmarshalText
Employee
為JSON字串要轉成的struct。定義type Date
為time.Time
並實作encoding.UnmarshalText
及encoding.Marshaler
介面。
實作TextUnmarshaler.UnmarshalText()
自訂text轉換為物件的邏輯;
實作TextMarshaler.MarshalText()
自訂轉換物件為text的邏輯。
main.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
var df = "2006-01-02"
type Date time.Time
func (d *Date) UnmarshalText(text []byte) error {
t, err := time.Parse(df, string(text))
if err != nil {
return err
}
*d = Date(t)
return nil
}
func (d Date) MarshalText() (text []byte, err error) {
s := time.Time(d).Format(df)
return []byte(s), nil
}
func (c Date) String() string {
return time.Time(c).Format(df)
}
type Employee struct {
Id int
Name string
Age int
CreatedDate Date
}
func main() {
http.HandleFunc("/employee", func(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
var emp Employee
if err := json.NewDecoder(r.Body).Decode(&emp); err != nil {
panic(err)
}
fmt.Println(emp.CreatedDate) // 2021-01-19
json.NewEncoder(rw).Encode(emp)
default:
http.Error(rw, "Method not allowed", http.StatusMethodNotAllowed)
}
})
http.ListenAndServe(":8080", nil)
}
測試
啟動應用程式後在命令列以cURL發出以下請求。
$ curl -X POST "http://localhost:8080/employee" -H 'content-type: application/json' -d '{"id": 1, "name": "john", "age": 33, "createdDate": "2021-01-19"}'
在console印出以下。
2021-01-19
回應結果如下:
{"Id":1,"Name":"john","Age":33,"CreatedDate":"2021-01-19"}
沒有留言:
張貼留言