gin 接口开发 - 用户输入自动 TrimSpace
最近在思考一个问题,针对用户的输入,能不能快速校验?
比方说下面的 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.Request 的 ParseForm 和 ParseMultipartForm 方法,它只会解析一次。
而 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的更多相关文章
- jQuery实现用户输入自动完成功能
jQuery实现用户输入自动完成功能 利用jQuery UI中Auto-complete插件实现输入自动完成功能,大家在使用诸如淘宝.京东等电商平台搜索商品时,往往只要输入商品的一些特殊字符,就可以显 ...
- FastAPI(六十八)实战开发《在线课程学习系统》接口开发--用户 个人信息接口开发
在之前的文章:FastAPI(六十七)实战开发<在线课程学习系统>接口开发--用户登陆接口开发,今天实战:用户 个人信息接口开发. 在开发个人信息接口的时候,我们要注意了,因为我们不一样的 ...
- FastAPI(六十七)实战开发《在线课程学习系统》接口开发--用户登陆接口开发
接上一篇文章FastAPI(六十六)实战开发<在线课程学习系统>接口开发--用户注册接口开发.这次我们分享实际开发--用户登陆接口开发. 我们先来梳理下逻辑 1.查询用户是否存在2.校验密 ...
- 【原】ComboBoxety用户输入自动匹配
//在界面构造函数里加入下面两行代码 this.cbbDepartureAirport.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode ...
- FastAPI(六十九)实战开发《在线课程学习系统》接口开发--修改密码
之前我们分享了FastAPI(六十八)实战开发<在线课程学习系统>接口开发--用户 个人信息接口开发.这次我们去分享实战开发<在线课程学习系统>接口开发--修改密码 我们梳理一 ...
- 03 . Gin+Vue开发一个线上外卖应用(用户数据创建,插入,跨域处理)
功能和背景介绍 在项目的登录功能中,如果在登录时发现用户名和密码在用户表中不存在,会自动将用户名和密码保存在用户表中,创建一个新的用户. 因此,除了使用手机号和验证码登录以外,还支持使用用户名.密码进 ...
- C#微信公众号接口开发,灵活利用网页授权、带参数二维码、模板消息,提升用户体验之完成用户绑定个人微信及验证码获取
一.前言 当下微信公众号几乎已经是每个公司必备的,但是大部分微信公众账号用户体验都欠佳,特别是涉及到用户绑定等,需要用户进行复杂的操作才可以和网站绑定,或者很多公司直接不绑定,而是每次都让用户填写账号 ...
- 微信小程序开发系列五:微信小程序中如何响应用户输入事件
微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 微信小程序开发系列四:微信小程序 ...
- jquery+php实现用户输入搜索内容时自动提示
index.html <html> <head> <meta charset=;} #search_auto li a:hover{background:#D8D ...
- AutoCompleteTextView 与sqlite绑定实现记住用户输入的内容并自动提示
把用户输入的内容保存到数据库表中,然后用户输入时,进行模糊查询并把查询结果附到AutoCompleteTextView中. 1:activity_main.xml <LinearLayout x ...
随机推荐
- 带你用三种不同的工具体验AI作诗
摘要:本实验基于华为云API Arts和API Explorer,向用户介绍诗歌生成API,指导用户使用华为云工具,体验AI作诗的过程. 本文分享自华为云社区<AI语言能力体验:通过三种不同的工 ...
- RHEL 7配置HAProxy实现Web负载均衡
本文将简单介绍使用HAProxy实现web负载均衡,主要内容包括基于权重的轮询.为HAProxy配置https.配置http重定向为https.配置HAProxy使用独立日志. 一.测试环境 HAPr ...
- mysql+proxysql+replication-manager的主从半同步复制+高可用+读写分离
环境: AlmaLinux release 9.1 MySQL Community Server Ver 8.0.33 Replication Manager v2.2.40 for MariaDB ...
- Android JAVA连接MQTT,以及常见问题
本文介绍如何使用Android(JAVA)客户机连接MQTT服务器 第一步先引入MQTT 在 build.gradle 添加以下: dependencies { implementation 'org ...
- 笔记:C++学习之旅---面向对象程序的设计1
笔记:C++学习之旅---面向对象程序的设计1 面向对象的主要特征 1.抽象 2.封装 3.继承 4.多态 抽象:将程序的每一部分都看作一个抽象的对象,即程序有一组抽象的对象组成的更复杂点,这些对象根 ...
- 牛客网:华为机试题(python版本)
输入一行:input() 输入的一行有多个信息:input().split() 有多组测试用例(多组同时输入): while true try except... 1.计算字符串最后一个单词的长度,单 ...
- [OpenCV-Python] 7 把鼠标当画笔
文章目录 OpenCV-Python: II OpenCV 中的 Gui 特性 7 把鼠标当画笔 7.1 简单演示 7.2 高级一点的示例 OpenCV-Python: II OpenCV 中的 Gu ...
- cefsharp学习笔记
环境:VS2015+cefsharp 57.0 全部代码如下: 1.要初始化,否则不能刷新 using System; using CefSharp; using System.Collections ...
- 2020-10-16:CAS知道么?底层实现? 会引发什么问题?如何解决ABA问题?
福哥答案2020-10-16:#福大大架构师每日一题# 简单回答:cmpxchg原子指令.aba,循环开销大,一个共享变量. [知乎](https://www.zhihu.com/question/4 ...
- Play to Earn Games
什么是P2E游戏 P2E 游戏(Play to Earn Games)指的是在区块链游戏中,玩家可以通过完成任务.收获资源.挖矿或游戏中的其他活动以获得成就来赚取游戏内的资产(NFT)或代币(Toke ...