github.com/wangyougui/gf/v2@v2.6.5/net/ghttp/ghttp_request_param_request.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package ghttp 8 9 import ( 10 "github.com/wangyougui/gf/v2/container/gvar" 11 "github.com/wangyougui/gf/v2/internal/empty" 12 "github.com/wangyougui/gf/v2/net/goai" 13 "github.com/wangyougui/gf/v2/os/gstructs" 14 "github.com/wangyougui/gf/v2/util/gconv" 15 "github.com/wangyougui/gf/v2/util/gutil" 16 ) 17 18 // GetRequest retrieves and returns the parameter named `key` passed from the client and 19 // custom params as interface{}, no matter what HTTP method the client is using. The 20 // parameter `def` specifies the default value if the `key` does not exist. 21 // 22 // GetRequest is one of the most commonly used functions for retrieving parameters. 23 // 24 // Note that if there are multiple parameters with the same name, the parameters are 25 // retrieved and overwrote in order of priority: router < query < body < form < custom. 26 func (r *Request) GetRequest(key string, def ...interface{}) *gvar.Var { 27 value := r.GetParam(key) 28 if value.IsNil() { 29 value = r.GetForm(key) 30 } 31 if value.IsNil() { 32 r.parseBody() 33 if len(r.bodyMap) > 0 { 34 if v := r.bodyMap[key]; v != nil { 35 value = gvar.New(v) 36 } 37 } 38 } 39 if value.IsNil() { 40 value = r.GetQuery(key) 41 } 42 if value.IsNil() { 43 value = r.GetRouter(key) 44 } 45 if !value.IsNil() { 46 return value 47 } 48 if len(def) > 0 { 49 return gvar.New(def[0]) 50 } 51 return nil 52 } 53 54 // GetRequestMap retrieves and returns all parameters passed from the client and custom params 55 // as the map, no matter what HTTP method the client is using. The parameter `kvMap` specifies 56 // the keys retrieving from client parameters, the associated values are the default values 57 // if the client does not pass the according keys. 58 // 59 // GetRequestMap is one of the most commonly used functions for retrieving parameters. 60 // 61 // Note that if there are multiple parameters with the same name, the parameters are retrieved 62 // and overwrote in order of priority: router < query < body < form < custom. 63 func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]interface{} { 64 r.parseQuery() 65 r.parseForm() 66 r.parseBody() 67 var ( 68 ok, filter bool 69 ) 70 if len(kvMap) > 0 && kvMap[0] != nil { 71 filter = true 72 } 73 m := make(map[string]interface{}) 74 for k, v := range r.routerMap { 75 if filter { 76 if _, ok = kvMap[0][k]; !ok { 77 continue 78 } 79 } 80 m[k] = v 81 } 82 for k, v := range r.queryMap { 83 if filter { 84 if _, ok = kvMap[0][k]; !ok { 85 continue 86 } 87 } 88 m[k] = v 89 } 90 for k, v := range r.formMap { 91 if filter { 92 if _, ok = kvMap[0][k]; !ok { 93 continue 94 } 95 } 96 m[k] = v 97 } 98 for k, v := range r.bodyMap { 99 if filter { 100 if _, ok = kvMap[0][k]; !ok { 101 continue 102 } 103 } 104 m[k] = v 105 } 106 for k, v := range r.paramsMap { 107 if filter { 108 if _, ok = kvMap[0][k]; !ok { 109 continue 110 } 111 } 112 m[k] = v 113 } 114 // File uploading. 115 if r.MultipartForm != nil { 116 for name := range r.MultipartForm.File { 117 if uploadFiles := r.GetUploadFiles(name); len(uploadFiles) == 1 { 118 m[name] = uploadFiles[0] 119 } else { 120 m[name] = uploadFiles 121 } 122 } 123 } 124 // Check none exist parameters and assign it with default value. 125 if filter { 126 for k, v := range kvMap[0] { 127 if _, ok = m[k]; !ok { 128 m[k] = v 129 } 130 } 131 } 132 return m 133 } 134 135 // GetRequestMapStrStr retrieve and returns all parameters passed from the client and custom 136 // params as map[string]string, no matter what HTTP method the client is using. The parameter 137 // `kvMap` specifies the keys retrieving from client parameters, the associated values are the 138 // default values if the client does not pass. 139 func (r *Request) GetRequestMapStrStr(kvMap ...map[string]interface{}) map[string]string { 140 requestMap := r.GetRequestMap(kvMap...) 141 if len(requestMap) > 0 { 142 m := make(map[string]string, len(requestMap)) 143 for k, v := range requestMap { 144 m[k] = gconv.String(v) 145 } 146 return m 147 } 148 return nil 149 } 150 151 // GetRequestMapStrVar retrieve and returns all parameters passed from the client and custom 152 // params as map[string]*gvar.Var, no matter what HTTP method the client is using. The parameter 153 // `kvMap` specifies the keys retrieving from client parameters, the associated values are the 154 // default values if the client does not pass. 155 func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[string]*gvar.Var { 156 requestMap := r.GetRequestMap(kvMap...) 157 if len(requestMap) > 0 { 158 m := make(map[string]*gvar.Var, len(requestMap)) 159 for k, v := range requestMap { 160 m[k] = gvar.New(v) 161 } 162 return m 163 } 164 return nil 165 } 166 167 // GetRequestStruct retrieves all parameters passed from the client and custom params no matter 168 // what HTTP method the client is using, and converts them to give the struct object. Note that 169 // the parameter `pointer` is a pointer to the struct object. 170 // The optional parameter `mapping` is used to specify the key to attribute mapping. 171 func (r *Request) GetRequestStruct(pointer interface{}, mapping ...map[string]string) error { 172 _, err := r.doGetRequestStruct(pointer, mapping...) 173 return err 174 } 175 176 func (r *Request) doGetRequestStruct(pointer interface{}, mapping ...map[string]string) (data map[string]interface{}, err error) { 177 data = r.GetRequestMap() 178 if data == nil { 179 data = map[string]interface{}{} 180 } 181 // Default struct values. 182 if err = r.mergeDefaultStructValue(data, pointer); err != nil { 183 return data, nil 184 } 185 // `in` Tag Struct values. 186 if err = r.mergeInTagStructValue(data, pointer); err != nil { 187 return data, nil 188 } 189 190 return data, gconv.Struct(data, pointer, mapping...) 191 } 192 193 // mergeDefaultStructValue merges the request parameters with default values from struct tag definition. 194 func (r *Request) mergeDefaultStructValue(data map[string]interface{}, pointer interface{}) error { 195 fields := r.serveHandler.Handler.Info.ReqStructFields 196 if len(fields) > 0 { 197 var ( 198 foundKey string 199 foundValue interface{} 200 ) 201 for _, field := range fields { 202 if tagValue := field.TagDefault(); tagValue != "" { 203 foundKey, foundValue = gutil.MapPossibleItemByKey(data, field.Name()) 204 if foundKey == "" { 205 data[field.Name()] = tagValue 206 } else { 207 if empty.IsEmpty(foundValue) { 208 data[foundKey] = tagValue 209 } 210 } 211 } 212 } 213 return nil 214 } 215 216 // provide non strict routing 217 tagFields, err := gstructs.TagFields(pointer, defaultValueTags) 218 if err != nil { 219 return err 220 } 221 if len(tagFields) > 0 { 222 var ( 223 foundKey string 224 foundValue interface{} 225 ) 226 for _, field := range tagFields { 227 foundKey, foundValue = gutil.MapPossibleItemByKey(data, field.Name()) 228 if foundKey == "" { 229 data[field.Name()] = field.TagValue 230 } else { 231 if empty.IsEmpty(foundValue) { 232 data[foundKey] = field.TagValue 233 } 234 } 235 } 236 } 237 238 return nil 239 } 240 241 // mergeInTagStructValue merges the request parameters with header or cookie values from struct `in` tag definition. 242 func (r *Request) mergeInTagStructValue(data map[string]interface{}, pointer interface{}) error { 243 fields := r.serveHandler.Handler.Info.ReqStructFields 244 if len(fields) > 0 { 245 var ( 246 foundKey string 247 foundValue interface{} 248 headerMap = make(map[string]interface{}) 249 cookieMap = make(map[string]interface{}) 250 ) 251 252 for k, v := range r.Header { 253 if len(v) > 0 { 254 headerMap[k] = v[0] 255 } 256 } 257 258 for _, cookie := range r.Cookies() { 259 cookieMap[cookie.Name] = cookie.Value 260 } 261 262 for _, field := range fields { 263 if tagValue := field.TagIn(); tagValue != "" { 264 switch tagValue { 265 case goai.ParameterInHeader: 266 foundHeaderKey, foundHeaderValue := gutil.MapPossibleItemByKey(headerMap, field.TagPriorityName()) 267 if foundHeaderKey != "" { 268 foundKey, foundValue = gutil.MapPossibleItemByKey(data, foundHeaderKey) 269 if foundKey == "" { 270 data[field.Name()] = foundHeaderValue 271 } else { 272 if empty.IsEmpty(foundValue) { 273 data[foundKey] = foundHeaderValue 274 } 275 } 276 } 277 case goai.ParameterInCookie: 278 foundCookieKey, foundCookieValue := gutil.MapPossibleItemByKey(cookieMap, field.TagPriorityName()) 279 if foundCookieKey != "" { 280 foundKey, foundValue = gutil.MapPossibleItemByKey(data, foundCookieKey) 281 if foundKey == "" { 282 data[field.Name()] = foundCookieValue 283 } else { 284 if empty.IsEmpty(foundValue) { 285 data[foundKey] = foundCookieValue 286 } 287 } 288 } 289 } 290 } 291 } 292 } 293 return nil 294 }