conv.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package param
  2. import (
  3. "fmt"
  4. "reflect"
  5. beecontext "github.com/cnlh/nps/vender/github.com/astaxie/beego/context"
  6. "github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
  7. )
  8. // ConvertParams converts http method params to values that will be passed to the method controller as arguments
  9. func ConvertParams(methodParams []*MethodParam, methodType reflect.Type, ctx *beecontext.Context) (result []reflect.Value) {
  10. result = make([]reflect.Value, 0, len(methodParams))
  11. for i := 0; i < len(methodParams); i++ {
  12. reflectValue := convertParam(methodParams[i], methodType.In(i), ctx)
  13. result = append(result, reflectValue)
  14. }
  15. return
  16. }
  17. func convertParam(param *MethodParam, paramType reflect.Type, ctx *beecontext.Context) (result reflect.Value) {
  18. paramValue := getParamValue(param, ctx)
  19. if paramValue == "" {
  20. if param.required {
  21. ctx.Abort(400, fmt.Sprintf("Missing parameter %s", param.name))
  22. } else {
  23. paramValue = param.defaultValue
  24. }
  25. }
  26. reflectValue, err := parseValue(param, paramValue, paramType)
  27. if err != nil {
  28. logs.Debug(fmt.Sprintf("Error converting param %s to type %s. Value: %v, Error: %s", param.name, paramType, paramValue, err))
  29. ctx.Abort(400, fmt.Sprintf("Invalid parameter %s. Can not convert %v to type %s", param.name, paramValue, paramType))
  30. }
  31. return reflectValue
  32. }
  33. func getParamValue(param *MethodParam, ctx *beecontext.Context) string {
  34. switch param.in {
  35. case body:
  36. return string(ctx.Input.RequestBody)
  37. case header:
  38. return ctx.Input.Header(param.name)
  39. case path:
  40. return ctx.Input.Query(":" + param.name)
  41. default:
  42. return ctx.Input.Query(param.name)
  43. }
  44. }
  45. func parseValue(param *MethodParam, paramValue string, paramType reflect.Type) (result reflect.Value, err error) {
  46. if paramValue == "" {
  47. return reflect.Zero(paramType), nil
  48. }
  49. parser := getParser(param, paramType)
  50. value, err := parser.parse(paramValue, paramType)
  51. if err != nil {
  52. return result, err
  53. }
  54. return safeConvert(reflect.ValueOf(value), paramType)
  55. }
  56. func safeConvert(value reflect.Value, t reflect.Type) (result reflect.Value, err error) {
  57. defer func() {
  58. if r := recover(); r != nil {
  59. var ok bool
  60. err, ok = r.(error)
  61. if !ok {
  62. err = fmt.Errorf("%v", r)
  63. }
  64. }
  65. }()
  66. result = value.Convert(t)
  67. return
  68. }