最近在思考一个问题,针对用户的输入,能不能快速校验?

比方说下面的 struct,大家用过 gin 的就知道,支持指定某个字段为 required,用户如果不输入,就检验不通过。

type LoginForm struct {
Username string `json:"username" form:"username"`
Key string `json:"key" form:"key"`
Sign string `json:"sign" form:"sign"`
}

然而,我们不能指望用户输入了,这个字段就是可以用的!例如他提交了这个表单:

{
"username": " ",
"key": "value",
"sign": " "
}

也就是说,用户输入了空格,就成功躲避我们的校验,所以我们不得不再校验一次:

form.Username = strings.TrimSpace(form.Username)
form.Key = strings.TrimSpace(form.Key)
form.Sign = strings.TrimSpace(form.Sign)

……显然,非常不优雅!如果字段多的话,满屏都是这样子的代码,相信屏幕前的你也是受不了的!

那有没有好办法?

因为公司存在 PHP 业务,为了兼容,JSON 的解析使用了 jsoniter 这个第三方包。如果你也是使用 gin 框架,别忘了编译指定 -tags=jsoniter 构建标签:

go build -tags=jsoniter -o ./${PROJECT_NAME} ./cmd/server

而 jsoniter 有个非常强大的功能,支持在解析类型的时候,执行你给定的钩子!

于是只要我们在项目启动的时候注册以下钩子函数:

当解析到 string 的时候,自动帮我们 TrimSpace !!!

func init() {
jsonAutoTrimSpace()
} func jsonAutoTrimSpace() {
jsoniter.RegisterTypeDecoderFunc("string", func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
s := strings.TrimSpace(iter.ReadString())
*((*string)(ptr)) = s
})
}

至此,JSON 数据解析的时候,就支持自动去掉空白字符了。但是有时候参数不是 JSON 传递的,是通过 URL 的参数形式、或者是 POST 表单,该怎么办?

这个大家可以看下 http.RequestParseFormParseMultipartForm 方法,它只会解析一次。

而 gin 底层的 Bind 也是调用了这两个方法,我们可以在用户 Bind 之前,调用 ParseForm 和 ParseMultipartForm 方法,对里面的 Value 遍历并 TrimSpace 就好了!后面用户第二次调用,拿到的也是我们 TrimSpace 后的内容了。

func shouldBindForm(req *http.Request) (err error) {
if err = req.ParseForm(); err != nil {
return
}
const defaultMemory = 32 << 20
if err = req.ParseMultipartForm(defaultMemory); err != nil {
if err == http.ErrNotMultipart {
err = nil
} else {
return
}
}
for k, v := range req.Form {
for i, s := range v {
req.Form[k][i] = strings.TrimSpace(s)
}
}
for k, v := range req.PostForm {
for i, s := range v {
req.PostForm[k][i] = strings.TrimSpace(s)
}
}
if req.MultipartForm != nil {
for k, v := range req.MultipartForm.Value {
for i, s := range v {
req.MultipartForm.Value[k][i] = strings.TrimSpace(s)
}
}
}
return
}

shouldBindForm 的调用时机,需要检查一下 ContentType,如果是表单,或者是 GET 请求,就执行一下,具体可以参考 gin 的实现。


文章来源于本人博客,发布于 2019-09-08,原文链接:https://imlht.com/archives/193/

gin 接口开发 - 用户输入自动 TrimSpace的更多相关文章

  1. jQuery实现用户输入自动完成功能

    jQuery实现用户输入自动完成功能 利用jQuery UI中Auto-complete插件实现输入自动完成功能,大家在使用诸如淘宝.京东等电商平台搜索商品时,往往只要输入商品的一些特殊字符,就可以显 ...

  2. FastAPI(六十八)实战开发《在线课程学习系统》接口开发--用户 个人信息接口开发

    在之前的文章:FastAPI(六十七)实战开发<在线课程学习系统>接口开发--用户登陆接口开发,今天实战:用户 个人信息接口开发. 在开发个人信息接口的时候,我们要注意了,因为我们不一样的 ...

  3. FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发

    接上一篇文章FastAPI(六十六)实战开发<在线课程学习系统>接口开发--用户注册接口开发.这次我们分享实际开发--用户登陆接口开发. 我们先来梳理下逻辑 1.查询用户是否存在2.校验密 ...

  4. 【原】ComboBoxety用户输入自动匹配

    //在界面构造函数里加入下面两行代码 this.cbbDepartureAirport.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode ...

  5. FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码

    之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...

  6. 03 . Gin+Vue开发一个线上外卖应用(用户数据创建,插入,跨域处理)

    功能和背景介绍 在项目的登录功能中,如果在登录时发现用户名和密码在用户表中不存在,会自动将用户名和密码保存在用户表中,创建一个新的用户. 因此,除了使用手机号和验证码登录以外,还支持使用用户名.密码进 ...

  7. C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取

    一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...

  8. 微信小程序开发系列五:微信小程序中如何响应用户输入事件

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...

  9. jquery+php实现用户输入搜索内容时自动提示

    index.html <html> <head>     <meta charset=;} #search_auto li a:hover{background:#D8D ...

  10. AutoCompleteTextView 与sqlite绑定实现记住用户输入的内容并自动提示

    把用户输入的内容保存到数据库表中,然后用户输入时,进行模糊查询并把查询结果附到AutoCompleteTextView中. 1:activity_main.xml <LinearLayout x ...

随机推荐

  1. vue中通过$emit实现子向父通信

    本篇讨论vue中使用$emit实现子向父通信, 第一步:我们在父组件中注册子组件,然后再给子组件标签添加一个自定义事件监听,这样在子组件实例上就绑定了一个自定义的事件add. 后面如果触发add事件, ...

  2. 区块链——Lab2

    区块链的典型数据结构 比特币:UTXO模型,以交易后找零为中心 ETH:Account 模型,以账户余额为中心(就是账户的形式) 区块链交易 用户发起交易 矿工验证交易(能够得到 区块奖励) 验证成功 ...

  3. 迁移学习(MEnsA)《MEnsA: Mix-up Ensemble Average for Unsupervised Multi Target Domain Adaptation on 3D Point Clouds》

    论文信息 论文标题:MEnsA: Mix-up Ensemble Average for Unsupervised Multi Target Domain Adaptation on 3D Point ...

  4. YOLO4论文中文版

    文章目录 YOLO4论文中文版 摘要 1.介绍 2.相关工作 2.1.目标检测模型 2.2.Bag of freebies 2.3.Bag of specials 3.方法 3.1.架构选择 3.2. ...

  5. 自定义alert、confirm、prompt的vue组件

    Prompt.vue组件 说明: 通过props定制定制的Prompt,可选值 mode 默认值:prompt, 其他模式:confirm.message(简单的提示,可设置提示显示时间,类似aler ...

  6. #Python实例 计算外卖配送距离(基于百度API接口)---第二篇

    https://www.cnblogs.com/simone331/p/17218019.html 在上一篇中,我们计算了两点的距离(链接为上篇文章),但是具体业务中,往往会存在一次性计算多组,上百甚 ...

  7. 2022-12-07:删除重复的电子邮箱。删除重复数据后,id=3的数据被删除。请问sql语句如何写? DROP TABLE IF EXISTS `person`; CREATE TABLE `per

    2022-12-07:删除重复的电子邮箱.删除重复数据后,id=3的数据被删除.请问sql语句如何写? DROP TABLE IF EXISTS `person`; CREATE TABLE `per ...

  8. 2022-11-18:给定一个数组arr,表示连续n天的股价,数组下标表示第几天 指标X:任意两天的股价之和 - 此两天间隔的天数 比如 第3天,价格是10 第9天,价格是30 那么第3天和第9天的指

    2022-11-18:给定一个数组arr,表示连续n天的股价,数组下标表示第几天 指标X:任意两天的股价之和 - 此两天间隔的天数 比如 第3天,价格是10 第9天,价格是30 那么第3天和第9天的指 ...

  9. 2022-06-29:x = { a, b, c, d }, y = { e, f, g, h }, x、y两个小数组长度都是4。 如果有: a + e = b + f = c + g = d + h

    2022-06-29:x = { a, b, c, d }, y = { e, f, g, h }, x.y两个小数组长度都是4. 如果有: a + e = b + f = c + g = d + h ...

  10. 小知识:设置archive_lag_target参数强制日志切换

    为客户测试一个ADG场景问题,发现测试环境的日志切换频率过低,总是需要定期手工切换,这非常影响测试心情. 实际上,可以设置archive_lag_target参数强制日志切换. 比如设置: alter ...