Golang:基于go反射机制实现通用http参数与结构体的转换

文章目录

  • 前言
  • 一、Http Get参数转Go struct
    • 写成中间件形式
  • 二、 看看Gin的get参数怎么绑定的
    • Gin主要通过tag标签来,支持`uri`和`form`和`自定义tag`


前言

每次写http请求参数处理时候,都需要从Query里面取出来,然后赋值给Struct,每个接口都需要重复。那么,有没有什么方法,我只需要给定结构体类型,自动帮我解析参数呢?

一、Http Get参数转Go struct

func RequestGetParamsToStruct(s interface{}, m url.Values) error {
	st := reflect.TypeOf(s).Elem() // 获取type
	sv := reflect.ValueOf(s).Elem() // 获取value
	// 只需要遍历全部的go struct field ,复杂度O(N), url.Values操作是0(1)
	for i := 0; i < st.NumField(); i++ {
		// 从type里面获取tag
		name := st.Field(i).Tag.Get("json")
		v := m.Get(name)
		if len(v) == 0 {
			//fmt.Println("not found value in urlValues: key=", name)
			continue
		}
		val := reflect.ValueOf(v)
		// 类型匹配
		if st.Field(i).Type != val.Type() {
			return fmt.Errorf("Provided value type didn't match obj field type: %v != %v", st.Field(i).Type, val.Type())
		}
		// struct value 赋值
		sv.Field(i).Set(val)
	}
	return nil
}

写成中间件形式

Get Method

func MakeCommonGetRequest(req interface{}) func(_ context.Context, r *http.Request) (interface{}, error) {
	return func(_ context.Context, r *http.Request) (interface{}, error) {
		tempResp := reflect.New(reflect.TypeOf(req).Elem()).Interface()
		err := RequestGetParamsToStruct(tempResp, r.URL.Query())
		if err != nil {
			return nil, err
		}
		return tempResp, err
	}
}

Post Method

func  MakeCommonJsonRequest(req interface{}) func(_ context.Context, r *http.Request) (interface{}, error) {
	return func(_ context.Context, r *http.Request) (interface{}, error) {
		tempResp := reflect.New(reflect.TypeOf(req).Elem()).Interface()
		err := json.NewDecoder(r.Body).Decode(&tempResp)
		return tempResp, err
	}
}

二、 看看Gin的get参数怎么绑定的

Golang:基于go反射机制实现通用http参数与结构体的转换_第1张图片
Golang:基于go反射机制实现通用http参数与结构体的转换_第2张图片

Gin主要通过tag标签来,支持uriform自定义tag

在这里插入图片描述
Golang:基于go反射机制实现通用http参数与结构体的转换_第3张图片

Golang:基于go反射机制实现通用http参数与结构体的转换_第4张图片

Golang:基于go反射机制实现通用http参数与结构体的转换_第5张图片

你可能感兴趣的:(L0:计算机,#,L1:编程语言,golang,http,java)