1, first look at the official binding, time. Time will bind failed
2. Custom Bindings
Package Handleimport ("reflect" "StrConv" "Strings" "Github.com/labstack/echo" "Net/http" "Encoding/jso N "" FMT "" Errors "" Encoding/xml "" Time ") type Custombinder struct{}//Bind implements the ' Binder#bind ' functi On.func (b *custombinder) Bind (i interface{}, C echo. Context) (err error) {req: = C.request () if Req. ContentLength = = 0 {if req. Method = = echo. GET | | Req. Method = = echo. DELETE {If Err = B.binddata (i, C.queryparams (), "Query"); Err! = nil {return echo. Newhttperror (http. Statusbadrequest, Err. Error ())} return return echo. Newhttperror (http. Statusbadrequest, "Request body can ' t be empty")} CType: = req. Header.get (Echo. Headercontenttype) switch {case strings. Hasprefix (CType, Echo. Mimeapplicationjson): If Err = json. Newdecoder (req. Body). Decode (i); Err! = Nil {if ute, OK: = Err. ( *json. UNMARSHALTYPEERROR); OK {return echo. NewhTtperror (http. Statusbadrequest, FMT. Sprintf ("Unmarshal type Error:expected=%v, Got=%v, Field=%v, Offset=%v", Ute. Type, Ute. Value, Ute. Field, Ute. Offset)} else if SE, OK: = Err. (*json. SyntaxError); OK {return echo. Newhttperror (http. Statusbadrequest, FMT. Sprintf ("Syntax error:offset=%v, Error=%v", SE. Offset, SE. Error ())} else {return echo. Newhttperror (http. Statusbadrequest, Err. Error ())}} case strings. Hasprefix (CType, Echo. Mimeapplicationxml), strings. Hasprefix (CType, Echo. Mimetextxml): If Err = XML. Newdecoder (req. Body). Decode (i); Err! = Nil {if ute, OK: = Err. ( *xml. UNSUPPORTEDTYPEERROR); OK {return echo. Newhttperror (http. Statusbadrequest, FMT. Sprintf ("Unsupported type error:type=%v, Error=%v", Ute. Type, Ute. Error ()))} else if SE, OK: = Err. (*xml. SyntaxError); OK {return echo. Newhttperror (http. Statusbadrequest, FMT. Sprintf ("Syntax error:line=%v, Error=%v ", SE. Line, SE. Error ())} else {return echo. Newhttperror (http. Statusbadrequest, Err. Error ())}} case strings. Hasprefix (CType, Echo. Mimeapplicationform), strings. Hasprefix (CType, Echo. Mimemultipartform): params, err: = C.formparams () if err! = Nil {return echo. Newhttperror (http. Statusbadrequest, Err. Error ())} If Err = B.binddata (i, params, "form"); Err! = Nil {return echo. Newhttperror (http. Statusbadrequest, Err. Error ())} Default:return Echo. Errunsupportedmediatype} return}func (b *custombinder) binddata (PTR interface{}, data map[string][]string, tag Stri NG) Error {typ: = reflect. TypeOf (PTR). Elem () Val: = reflect. ValueOf (PTR). Elem () if Typ. Kind ()! = reflect. Struct {return errors. New ("binding element must is a struct")} for I: = 0; I < Typ. Numfield (); i++ {typefield: = Typ. Field (i) Structfield: = val. Field (iIf!structfield.canset () {continue} Structfieldkind: = Structfield.kind () input FieldName: = TypeField.Tag.Get (Tag) If inputfieldname = = "" {inputfieldname = Typefield.name If tag is nil, we inspect if the field is a struct. If _, OK: = Bindunmarshaler (Structfield);!ok && Structfieldkind = = reflect. Struct {err: = B.binddata (Structfield.addr (). Interface (), data, tag) if err! = Nil {return err} Conti Nue}} inputvalue, exists: = Data[inputfieldname] If!exists {//Go JSON. Unmarshal supports case insensitive binding. However the//URL params is bound case sensitive which is inconsistent. To//fix this we must check all of the maps values in a//case-insensitive search. Inputfieldname = strings. ToLower (Inputfieldname) For k, V: = Range Data {if strings. ToLower (k) = = inputfieldname {Inputvalue = v exists = True break }}} If!exists {continue}//Call this first, in CAs E we ' re dealing with a alias to an array type if OK, err: = Unmarshalfield (TypeField.Type.Kind (), inputvalue[0], s Tructfield); OK {if err! = Nil {return err} continue} Numelems: = Len (inputvalue) If structfieldkind = = reflect. Slice && numelems > 0 {sliceof: = Structfield.type (). Elem (). Kind () Slice: = reflect. Makeslice (Structfield.type (), Numelems, Numelems) for J: = 0; J < Numelems; J + + {if err: = Setwithpropertype (sliceof, inputvalue[j], slice. Index (j)); Err! = Nil {return err}} val. Field (i). Set (Slice)} else {if err: = Setwithpropertype (TypeField.Type.Kind (), inputvalue[0], Structfield); err ! = Nil {return err}}} return Nil}func Setwithpropertype (valuekind reflect. Kind, Val string, Structfield reflect. Value) error {//but also call it here, in case we ' re dealing with an array of bindunmarshalers if OK, err: = Unmar Shalfield (Valuekind, Val, Structfield); OK {return err} switch Valuekind {case reflect. Ptr:return Setwithpropertype (Structfield.elem (). Kind (), Val, Structfield.elem ()) case reflect. Int:return Setintfield (val, 0, Structfield) case reflect. Int8:return Setintfield (Val, 8, Structfield) case reflect. Int16:return Setintfield (Val, +, Structfield) case reflect. Int32:return Setintfield (Val, +, Structfield) case reflect. Int64:return Setintfield (Val, +, Structfield) case reflect. Uint:return Setuintfield (Val,0, Structfield) case reflect. Uint8:return Setuintfield (Val, 8, Structfield) case reflect. Uint16:return Setuintfield (Val, +, Structfield) case reflect. Uint32:return Setuintfield (Val, +, Structfield) case reflect. Uint64:return Setuintfield (Val, +, Structfield) case reflect. Bool:return Setboolfield (Val, Structfield) case reflect. Float32:return Setfloatfield (Val, +, Structfield) case reflect. Float64:return Setfloatfield (Val, +, Structfield) case reflect. String:structField.SetString (val) case reflect. Struct://Time type var T. Time var err error val = strings. Replace (Val, "00:00:00", "",-1) if Isvaliddate (val) {T, err = Parsedate (val) If Err = = Nil {Structfield.set (reflect). ValueOf (t))}} else if Isvalidtime (val) {T, err = Parsetime (val) If Err = = Nil { structfield.seT (reflect. ValueOf (t))}} break Default:return errors. New ("Unknown Type")} return Nil}func Unmarshalfield (valuekind reflect. Kind, Val string, field reflect. Value) (bool, error) {switch Valuekind {case reflect. Ptr:return Unmarshalfieldptr (val, field) Default:return Unmarshalfieldnonptr (Val, field)}}//Bindun Marshaler attempts to unmarshal a reflect. Value into a bindunmarshalerfunc bindunmarshaler (field reflect. Value) (Echo. Bindunmarshaler, bool) {ptr: = reflect. New (field. Type ()) if PTR. Caninterface () {iface: = ptr. Interface () If unmarshaler, OK: = Iface. (Echo. Bindunmarshaler); OK {return unmarshaler, OK}} return nil, False}func unmarshalfieldnonptr (Value string, field re Flect. Value) (bool, error) {if unmarshaler, OK: = Bindunmarshaler (field); OK {err: = Unmarshaler. Unmarshalparam (value) field. Set (reflect. ValueOf (Unmarshaler). Elem ()) returnTrue, err} return False, Nil}func unmarshalfieldptr (value string, field reflect. Value) (bool, error) {if field. Isnil () {//Initialize the pointer to a nil value field. Set (reflect. New (field. Type (). Elem ())} return Unmarshalfieldnonptr (Value, field. Elem ())}func Setintfield (value string, bitsize int, field reflect. Value) Error {if value = = "" {value = "0"} intval, err: = StrConv. parseint (value, ten, bitsize) if Err = = nil {field. Setint (Intval)} return Err}func Setuintfield (value string, bitsize int, field reflect. Value) Error {if value = = "" {value = "0"} uintval, err: = StrConv. Parseuint (value, ten, bitsize) if Err = = nil {field. Setuint (Uintval)} return Err}func Setboolfield (value string, field reflect. Value) Error {if value = = "" {value = "false"} boolval, err: = StrConv. Parsebool (value) if Err = = nil {field. Setbool (Boolval)} return Err}func SETFLOatfield (value string, bitsize int, field reflect. Value) Error {if value = = "" {value = "0.0"} floatval, err: = StrConv. Parsefloat (value, bitsize) if Err = = nil {field. SetFloat (Floatval)} return Err}func Parsetime (date string) (time. Time, error) {date = strings. Replace (date, "/", "-",-1) Date = strings. Replace (Date, ".", "-",-1) return time. Parse ("2006-01-02 15:04:05", date)}func parsedate (date string) (time. Time, error) {date = strings. Replace (date, "/", "-",-1) Date = strings. Replace (Date, ".", "-",-1) return time. Parse ("2006-01-02", date)}func Isvalidtime (s string) bool {_, Err: = time. Parse ("2006-01-02 15:04:05", s) if err! = Nil {return false} return True}func Isvaliddate (s string) bool {_, Err: = time. Parse ("2006-01-02", s) if err! = Nil {return false} return true}