request.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package httper
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "reflect"
  7. "strconv"
  8. "strings"
  9. "github.com/astaxie/beego/context"
  10. "go.uber.org/zap"
  11. )
  12. var (
  13. Debug = false
  14. DebugLog *zap.Logger
  15. )
  16. func FillRequireParams(ctx *context.Context, param interface{}, logID string) {
  17. v := reflect.ValueOf(param)
  18. if v.Kind() == reflect.Ptr {
  19. v = v.Elem()
  20. }
  21. if v.Kind() != reflect.Struct {
  22. SystemError("query is not a struct")
  23. }
  24. numField := v.NumField()
  25. for i := 0; i < numField; i++ {
  26. fillParams(ctx, v.Type().Field(i), v.Field(i))
  27. }
  28. if Debug && DebugLog != nil {
  29. data, _ := json.Marshal(param)
  30. DebugLog.Debug(logID, zap.String("request", string(data)))
  31. }
  32. }
  33. func furtherFillRequireParams(ctx *context.Context, param interface{}) {
  34. v := reflect.ValueOf(param)
  35. if v.Kind() == reflect.Ptr {
  36. v = v.Elem()
  37. }
  38. if v.Kind() != reflect.Struct {
  39. SystemError("query is not a struct")
  40. }
  41. numField := v.NumField()
  42. for i := 0; i < numField; i++ {
  43. fillParams(ctx, v.Type().Field(i), v.Field(i))
  44. }
  45. }
  46. func fillParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  47. //fmt.Println(ctx.Input.Context.Request.Header)
  48. switch field.Tag.Get("in") {
  49. case "header":
  50. fillHeaderParams(ctx, field, val)
  51. case "body":
  52. fillBodyParams(ctx, field, val)
  53. case "path":
  54. fillPathParams(ctx, field, val)
  55. case "formData":
  56. fallthrough
  57. case "query":
  58. fillQueryParams(ctx, field, val)
  59. default:
  60. if !val.IsValid() || !val.CanAddr() || !val.CanSet() {
  61. SystemError("value can not set")
  62. }
  63. furtherFillRequireParams(ctx, val.Addr().Interface())
  64. }
  65. }
  66. func fillBodyParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  67. if !val.IsValid() || !val.CanAddr() || !val.CanSet() {
  68. SystemError("value can not set")
  69. }
  70. if val.Kind() == reflect.Ptr {
  71. val = val.Elem()
  72. }
  73. body := ctx.Input.RequestBody
  74. switch field.Tag.Get("decode") {
  75. case "base64":
  76. body, _ = base64.StdEncoding.DecodeString(string(body))
  77. }
  78. if err := json.Unmarshal(body, val.Addr().Interface()); err != nil {
  79. BadParamer(fmt.Sprintf("%s is not json error:%s", "body", err))
  80. }
  81. CheckBodyFiled(val.Addr().Interface())
  82. }
  83. func CheckBodyFiled(param interface{}, logID ...interface{}) {
  84. v := reflect.ValueOf(param)
  85. if v.Kind() == reflect.Ptr {
  86. v = v.Elem()
  87. }
  88. if v.Kind() != reflect.Struct {
  89. SystemError("body is not a struct")
  90. }
  91. numField := v.NumField()
  92. for i := 0; i < numField; i++ {
  93. if v.Field(i).Kind() == reflect.Struct { //递归检查
  94. CheckBodyFiled(v.Field(i).Addr().Interface())
  95. }
  96. field := v.Type().Field(i)
  97. val := v.Field(i)
  98. if reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface()) {
  99. if field.Tag.Get("required") == "true" {
  100. jsonTag := field.Tag.Get("json")
  101. if jsonTag == "" {
  102. jsonTag = field.Name
  103. }
  104. def := field.Tag.Get("default")
  105. fillValue(v.Field(i), def, true, jsonTag)
  106. }
  107. }
  108. }
  109. }
  110. func fillHeaderParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  111. jsonTag := field.Tag.Get("json")
  112. if jsonTag == "" {
  113. // 没有json标记,取变量的名称
  114. jsonTag = field.Name
  115. }
  116. var v string
  117. if v = ctx.Input.Header(jsonTag); v == "" {
  118. // 尝试将第一个字母转换为大写 测试环境使用 beego Swagger的bug
  119. firstUpperJsonTag := strings.ToUpper(jsonTag[0:1]) + string(jsonTag[1:])
  120. if v = ctx.Input.Header(firstUpperJsonTag); v == "" {
  121. v = field.Tag.Get("default")
  122. }
  123. }
  124. required := field.Tag.Get("required") == "true"
  125. if v == "" && required {
  126. BadParamer(fmt.Sprintf("%s is not exists in header", jsonTag))
  127. }
  128. fmt.Printf("header:%v\n", v)
  129. fillValue(val, v, required, jsonTag)
  130. }
  131. func fillPathParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  132. jsonTag := field.Tag.Get("json")
  133. if jsonTag == "" {
  134. // 没有json标记,取变量的名称
  135. jsonTag = field.Name
  136. }
  137. var v string
  138. if v = ctx.Input.Param(fmt.Sprintf(":%s", jsonTag)); v == "" {
  139. v = field.Tag.Get("default")
  140. }
  141. required := field.Tag.Get("required") == "true"
  142. if v == "" && required {
  143. BadParamer(fmt.Sprintf("%s is not exists in path", jsonTag))
  144. }
  145. fillValue(val, v, required, jsonTag)
  146. }
  147. func fillQueryParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  148. jsonTag := field.Tag.Get("json")
  149. if jsonTag == "" {
  150. // 没有json标记,取变量的名称
  151. jsonTag = field.Name
  152. }
  153. var v string
  154. if v = ctx.Input.Query(jsonTag); v == "" {
  155. v = field.Tag.Get("default")
  156. }
  157. required := field.Tag.Get("required") == "true"
  158. if v == "" && required {
  159. BadParamer(fmt.Sprintf("%s is not exists in query", jsonTag))
  160. }
  161. fillValue(val, v, required, jsonTag)
  162. }
  163. func fillValue(val reflect.Value, requestVal string, required bool, jsonTag string) {
  164. if val.Kind() == reflect.Ptr {
  165. val = val.Elem()
  166. }
  167. kind := val.Kind()
  168. switch {
  169. case kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 || kind == reflect.Uint64:
  170. if requestVal == "" && !required {
  171. requestVal = "0"
  172. }
  173. v, err := strconv.ParseUint(requestVal, 10, 64)
  174. if err != nil {
  175. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  176. }
  177. if !val.IsValid() || !val.CanSet() {
  178. SystemError("value can not set")
  179. }
  180. val.SetUint(v)
  181. case kind == reflect.Int || kind == reflect.Int64:
  182. if requestVal == "" && !required {
  183. requestVal = "0"
  184. }
  185. v, err := strconv.ParseInt(requestVal, 10, 64)
  186. if err != nil {
  187. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  188. }
  189. if !val.IsValid() || !val.CanSet() {
  190. SystemError("value can not set")
  191. }
  192. val.SetInt(v)
  193. case kind == reflect.Float64 || kind == reflect.Float32:
  194. if requestVal == "" && !required {
  195. requestVal = "0"
  196. }
  197. v, err := strconv.ParseFloat(requestVal, 64)
  198. if err != nil {
  199. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  200. }
  201. if !val.IsValid() || !val.CanSet() {
  202. SystemError("value can not set")
  203. }
  204. val.SetFloat(v)
  205. case kind == reflect.String:
  206. val.SetString(requestVal)
  207. case kind == reflect.Bool:
  208. if requestVal == "" {
  209. requestVal = "false"
  210. }
  211. v, err := strconv.ParseBool(requestVal)
  212. if err != nil {
  213. BadParamer(fmt.Sprintf("%s is not bool", jsonTag))
  214. }
  215. val.SetBool(v)
  216. default:
  217. BadParamer("type is not support")
  218. }
  219. }