You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.6 KiB

3 years ago
  1. package rpc
  2. import (
  3. "LEIT_PM/container"
  4. "errors"
  5. "fmt"
  6. "github.com/kataras/iris/v12"
  7. "reflect"
  8. )
  9. var DefaultValueParserBuilder = &ValueParserBuilder{}
  10. var DefaultMethodInvokerBuilder = &RouteBuilder{&MethodInvokerBuilder{&ValueParserBuilder{}, map[reflect.Type]ValueParser{container.RequestContextType: keepValue}}}
  11. type RouteBuilder struct {
  12. methodInvokerBuilder *MethodInvokerBuilder
  13. }
  14. func (builder *RouteBuilder) Build(serviceMethodName string, methodType container.Method) (container.HttpMethod, container.ParametersParser, string, error) {
  15. parameterParsers, err := builder.buildParameterParsers(serviceMethodName, methodType)
  16. if err != nil {
  17. return "", nil, "", err
  18. }
  19. parametersParser := func(context iris.Context) ([]interface{}, error) {
  20. if context.GetContentLength() <= 0 {
  21. return nil, errors.New(fmt.Sprintf("未找到内容!"))
  22. }
  23. var json interface{}
  24. err := context.ReadJSON(&json)
  25. if err != nil {
  26. return nil, err
  27. }
  28. if json == nil {
  29. return nil, errors.New(fmt.Sprintf("JSON解析失败!"))
  30. }
  31. jsonArray, ok := json.([]interface{})
  32. if !ok {
  33. return nil, errors.New(fmt.Sprintf("JSON数组解析失败!"))
  34. }
  35. parameters := make([]interface{}, len(parameterParsers))
  36. for i, parameterParser := range parameterParsers {
  37. parameters[i], err = parameterParser(jsonArray[i], fmt.Sprintf("#%d", i+1))
  38. if err != nil {
  39. return nil, err
  40. }
  41. }
  42. return parameters, nil
  43. }
  44. return container.HttpPost, parametersParser, "", nil
  45. }
  46. func (builder *RouteBuilder) buildParameterParsers(serviceMethodName string, methodType reflect.Type) ([]ValueParser, error) {
  47. if methodType.NumOut() < 1 || 2 < methodType.NumOut() {
  48. return nil, errors.New(fmt.Sprintf("返回值数量错误! Service: %s 返回值数量: %d", serviceMethodName, methodType.NumOut()))
  49. }
  50. if methodType.Out(methodType.NumOut()-1) != container.ErrorType {
  51. return nil, errors.New(fmt.Sprintf("最后一个返回值类型错误! Service: %s 类型:%s", serviceMethodName, methodType.Out(methodType.NumOut()-1)))
  52. }
  53. for i := 0; i < methodType.NumOut(); i++ {
  54. if ok, typeText := builder.methodInvokerBuilder.checkOutType(methodType.Out(i)); !ok {
  55. return nil, errors.New(fmt.Sprintf("不支持的返回值类型! Service: %s 参数: #%d 类型: %s", serviceMethodName, i+1, typeText))
  56. }
  57. }
  58. parameterParsers := make([]ValueParser, 0, 10)
  59. for i := 1; i < methodType.NumIn(); i++ {
  60. if parameterParser, err := builder.methodInvokerBuilder.buildParameterParser(serviceMethodName, methodType.In(i), i); err != nil {
  61. return nil, err
  62. } else {
  63. parameterParsers = append(parameterParsers, parameterParser)
  64. }
  65. }
  66. return parameterParsers, nil
  67. }