当前位置: 首页 > news >正文

go使用反射获取http.Request参数到结构体 - 实践

1. 为什么写这个工具

公司代码使用go原生写的,没有使用框架,接收前端的代码都使用的是req.FormValue()来接收,我觉得写了太多的接收参数的重复代码

2. Go代码
// ParseParams 解析前端传的参数到结构体
func ParseParams[T any](req *http.Request) (T, error) {
var t T
tType := reflect.TypeOf(t)
tValue := reflect.ValueOf(&t).Elem()
if tType.Kind() != reflect.Struct {
return t, fmt.Errorf("parseParams err: tType.Kind() != reflect.Struct")
}
for i := 0; i < tType.NumField(); i++ {
field := tType.Field(i)
value := tValue.Field(i)
err := setFieldValue(field, value, req)
if err != nil {
return t, err
}
}
return t, nil
}
// 设置对应的字段值
// 仅支持string, int, int64, int32, slice
func setFieldValue(field reflect.StructField, value reflect.Value, req *http.Request) error {
formValue := req.FormValue(field.Tag.Get("json"))
switch field.Type.Kind() {
case reflect.String:
value.SetString(formValue)
case reflect.Int, reflect.Int64, reflect.Int32:
atoi, err := strconv.Atoi(formValue)
if err != nil {
return fmt.Errorf("setFieldValue err: strconv.Atoi(%s) err: %v, field.Name: %v", formValue, err, field.Name)
}
value.SetInt(int64(atoi))
case reflect.Slice:
newSlice := reflect.New(field.Type)
if err := json.Unmarshal([]byte(formValue), newSlice.Interface()); err != nil {
return fmt.Errorf("setFieldValue err: json.Unmarshal(%s) err: %v, field.Name: %v", formValue, err, field.Name)
}
value.Set(newSlice.Elem())
default:
return fmt.Errorf("setFieldValue err: field.Type.Kind() not support: %v, field.Name: %v", field.Type.Kind(), field.Name)
}
return nil
}
3.使用
type TestReq struct {
ID int32 `json:"id"`
Name string `json:"name"`
SiteIdList []int32 `json:"siteIdList"`
DateTimeList []int64 `json:"dateTimeList"`
}
func TestParseParams(t *testing.T) {
req := &http.Request{
}
req.Form = map[string][]string{
"id": {
"1"
},
"name": {
"test"
},
"siteIdList": {
"[1,2,3]"
},
"dateTimeList": {
"[1694560000, 1694560060]"
},
}
params, err := ParseParams[TestReq](req)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(params)
}
目前只做了我常用的一些变量,后续可能会加入其他变量和字段校验
http://www.rkmt.cn/news/5962.html

相关文章:

  • centos7中mysql环境配置
  • Symfony学习笔记 - 利用Doctrine开发一个学生信息的增删查改
  • 实时内核中的调度程序节流
  • 我的ai 相关工具站
  • C#第十一章 023 024
  • centos7中scrapy运行环境配置
  • flutter配置国内镜像
  • 微信小程序 live-player 无声音
  • 陈燕的项目启动笔记
  • hyperv 管理的 ubuntu 虚拟机压缩磁盘
  • 【实战记录】使用 wp-cli 恢复/修改 WordPress 密码
  • Spring Boot 下 Druid 连接池:多维度优化打造卓越性能
  • vue3使用vue3-pdf-app预览pdf文档
  • 使用lvgl/lv_port_pc_visual_studio在PC上运行LVGL模拟器
  • Hutool 调用第三方接口报错
  • 丑东西经济学:全面分析
  • Python turtle 海龟画图入门指南
  • 啥是CPU
  • C# Avalonia 15- Animation- CodeAnimation
  • ubuntu 18.04安装mysql 8.0.41
  • C++ std::unordered_set
  • 如何将一个项目同时提交到GitHub和Gitee(码云)上
  • 易基因:Nat Genet/IF29:董朝斌团队ChIP-seq等揭示作物株型穗型发育调控新机制 助力表观遗传育种驯化改良(顶刊佳作)
  • Python TensorFlow的CNN-LSTM-GRU集成模型在边缘物联网数据IoT电动汽车充电站入侵检测应用
  • 源码管理—密钥硬编码问题
  • 数据库原理-第二章——关系型数据库
  • TCP协议与wireshark
  • ObjectSense 包与模块:代码组织的艺术
  • 数学之美 第一章读后感
  • 【ABSR出版】第二届农业工程与生物学国际研讨会(ISAEB 2025)