request.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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 "query":
  56. fillQueryParams(ctx, field, val)
  57. default:
  58. if !val.IsValid() || !val.CanAddr() || !val.CanSet() {
  59. SystemError("value can not set")
  60. }
  61. furtherFillRequireParams(ctx, val.Addr().Interface())
  62. }
  63. }
  64. func fillBodyParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  65. if !val.IsValid() || !val.CanAddr() || !val.CanSet() {
  66. SystemError("value can not set")
  67. }
  68. if val.Kind() == reflect.Ptr {
  69. val = val.Elem()
  70. }
  71. body := ctx.Input.RequestBody
  72. switch field.Tag.Get("decode") {
  73. case "base64":
  74. body, _ = base64.StdEncoding.DecodeString(string(body))
  75. }
  76. if err := json.Unmarshal(body, val.Addr().Interface()); err != nil {
  77. BadParamer(fmt.Sprintf("%s is not json error:%s", "body", err))
  78. }
  79. CheckBodyFiled(val.Addr().Interface())
  80. }
  81. func CheckBodyFiled(param interface{}, logID ...interface{}) {
  82. v := reflect.ValueOf(param)
  83. if v.Kind() == reflect.Ptr {
  84. v = v.Elem()
  85. }
  86. if v.Kind() != reflect.Struct {
  87. SystemError("body is not a struct")
  88. }
  89. numField := v.NumField()
  90. for i := 0; i < numField; i++ {
  91. if v.Field(i).Kind() == reflect.Struct { //递归检查
  92. CheckBodyFiled(v.Field(i).Addr().Interface())
  93. }
  94. field := v.Type().Field(i)
  95. val := v.Field(i)
  96. if reflect.DeepEqual(val.Interface(), reflect.Zero(val.Type()).Interface()) {
  97. if field.Tag.Get("required") == "true" {
  98. jsonTag := field.Tag.Get("json")
  99. if jsonTag == "" {
  100. jsonTag = field.Name
  101. }
  102. def := field.Tag.Get("default")
  103. fillValue(v.Field(i), def, true, jsonTag)
  104. }
  105. }
  106. }
  107. }
  108. func fillHeaderParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  109. jsonTag := field.Tag.Get("json")
  110. if jsonTag == "" {
  111. // 没有json标记,取变量的名称
  112. jsonTag = field.Name
  113. }
  114. var v string
  115. if v = ctx.Input.Header(jsonTag); v == "" {
  116. // 尝试将第一个字母转换为大写 测试环境使用 beego Swagger的bug
  117. firstUpperJsonTag := strings.ToUpper(jsonTag[0:1]) + string(jsonTag[1:])
  118. if v = ctx.Input.Header(firstUpperJsonTag); v == "" {
  119. v = field.Tag.Get("default")
  120. }
  121. }
  122. required := field.Tag.Get("required") == "true"
  123. if v == "" && required {
  124. BadParamer(fmt.Sprintf("%s is not exists in header", jsonTag))
  125. }
  126. fillValue(val, v, required, jsonTag)
  127. }
  128. func fillPathParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  129. jsonTag := field.Tag.Get("json")
  130. if jsonTag == "" {
  131. // 没有json标记,取变量的名称
  132. jsonTag = field.Name
  133. }
  134. var v string
  135. if v = ctx.Input.Param(fmt.Sprintf(":%s", jsonTag)); v == "" {
  136. v = field.Tag.Get("default")
  137. }
  138. required := field.Tag.Get("required") == "true"
  139. if v == "" && required {
  140. BadParamer(fmt.Sprintf("%s is not exists in path", jsonTag))
  141. }
  142. fillValue(val, v, required, jsonTag)
  143. }
  144. func fillQueryParams(ctx *context.Context, field reflect.StructField, val reflect.Value) {
  145. jsonTag := field.Tag.Get("json")
  146. if jsonTag == "" {
  147. // 没有json标记,取变量的名称
  148. jsonTag = field.Name
  149. }
  150. var v string
  151. if v = ctx.Input.Query(jsonTag); v == "" {
  152. v = field.Tag.Get("default")
  153. }
  154. required := field.Tag.Get("required") == "true"
  155. if v == "" && required {
  156. BadParamer(fmt.Sprintf("%s is not exists in query", jsonTag))
  157. }
  158. fillValue(val, v, required, jsonTag)
  159. }
  160. func fillValue(val reflect.Value, requestVal string, required bool, jsonTag string) {
  161. if val.Kind() == reflect.Ptr {
  162. val = val.Elem()
  163. }
  164. kind := val.Kind()
  165. switch {
  166. case kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 || kind == reflect.Uint64:
  167. if requestVal == "" && !required {
  168. requestVal = "0"
  169. }
  170. v, err := strconv.ParseUint(requestVal, 10, 64)
  171. if err != nil {
  172. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  173. }
  174. if !val.IsValid() || !val.CanSet() {
  175. SystemError("value can not set")
  176. }
  177. val.SetUint(v)
  178. case kind == reflect.Int || kind == reflect.Int64:
  179. if requestVal == "" && !required {
  180. requestVal = "0"
  181. }
  182. v, err := strconv.ParseInt(requestVal, 10, 64)
  183. if err != nil {
  184. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  185. }
  186. if !val.IsValid() || !val.CanSet() {
  187. SystemError("value can not set")
  188. }
  189. val.SetInt(v)
  190. case kind == reflect.Float64:
  191. if requestVal == "" && !required {
  192. requestVal = "0"
  193. }
  194. v, err := strconv.ParseFloat(requestVal, 64)
  195. if err != nil {
  196. BadParamer(fmt.Sprintf("%s is not uint", jsonTag))
  197. }
  198. if !val.IsValid() || !val.CanSet() {
  199. SystemError("value can not set")
  200. }
  201. val.SetFloat(v)
  202. case kind == reflect.String:
  203. val.SetString(requestVal)
  204. default:
  205. BadParamer("type is not support")
  206. }
  207. }