binding.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package response
  2. import (
  3. "fmt"
  4. "github.com/gin-gonic/gin/binding"
  5. "reflect"
  6. "strings"
  7. "sync"
  8. )
  9. const (
  10. _ uint8 = iota
  11. json
  12. xml
  13. yaml
  14. form
  15. query
  16. )
  17. var constructor = &bindConstructor{}
  18. type bindConstructor struct {
  19. cache map[string][]uint8
  20. mux sync.Mutex
  21. }
  22. func (e *bindConstructor) GetBindingForGin(d interface{}) []binding.Binding {
  23. bs := e.getBinding(reflect.TypeOf(d).String())
  24. if bs == nil {
  25. //重新构建
  26. bs = e.resolve(d)
  27. }
  28. gbs := make([]binding.Binding, len(bs))
  29. for i, b := range bs {
  30. switch b {
  31. case json:
  32. gbs[i] = binding.JSON
  33. case xml:
  34. gbs[i] = binding.XML
  35. case yaml:
  36. gbs[i] = binding.YAML
  37. case form:
  38. gbs[i] = binding.Form
  39. case query:
  40. gbs[i] = binding.Query
  41. default:
  42. gbs[i] = nil
  43. }
  44. }
  45. return gbs
  46. }
  47. func (e *bindConstructor) resolve(d interface{}) []uint8 {
  48. bs := make([]uint8, 0)
  49. qType := reflect.TypeOf(d).Elem()
  50. var tag reflect.StructTag
  51. var ok bool
  52. fmt.Println(qType.Kind())
  53. for i := 0; i < qType.NumField(); i++ {
  54. tag = qType.Field(i).Tag
  55. if _, ok = tag.Lookup("json"); ok {
  56. bs = append(bs, json)
  57. }
  58. if _, ok = tag.Lookup("xml"); ok {
  59. bs = append(bs, xml)
  60. }
  61. if _, ok = tag.Lookup("yaml"); ok {
  62. bs = append(bs, yaml)
  63. }
  64. if _, ok = tag.Lookup("form"); ok {
  65. bs = append(bs, form)
  66. }
  67. if _, ok = tag.Lookup("query"); ok {
  68. bs = append(bs, query)
  69. }
  70. if _, ok = tag.Lookup("uri"); ok {
  71. bs = append(bs, 0)
  72. }
  73. if t, ok := tag.Lookup("binding"); ok && strings.Index(t, "dive") > -1 {
  74. qValue := reflect.ValueOf(d)
  75. bs = append(bs, e.resolve(qValue.Field(i))...)
  76. continue
  77. }
  78. if t, ok := tag.Lookup("validate"); ok && strings.Index(t, "dive") > -1 {
  79. qValue := reflect.ValueOf(d)
  80. bs = append(bs, e.resolve(qValue.Field(i))...)
  81. }
  82. }
  83. return bs
  84. }
  85. func (e *bindConstructor) getBinding(name string) []uint8 {
  86. e.mux.Lock()
  87. defer e.mux.Unlock()
  88. return e.cache[name]
  89. }
  90. func (e *bindConstructor) setBinding(name string, bs []uint8) {
  91. e.mux.Lock()
  92. defer e.mux.Unlock()
  93. if e.cache == nil {
  94. e.cache = make(map[string][]uint8)
  95. }
  96. e.cache[name] = bs
  97. }