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 ...
随机推荐
- 在Vue中使用键盘事件,回调函数被执行两次
暂时先不考虑v-for的key,查看下面的代码 <template> <div> <form @submit.prevent="addTask"> ...
- iOS APP启动广告实现方式 与 APP唤端调用
APP启动广告功能实现要从2个方面思考 一是UI方案,怎样处理广告页与主页之间的切换方式. 二是广告页展示时机,是使用后台实时广告数据还是使用本地缓存广告数据.后台数据方式获取广告最新但是用户要等待后 ...
- 安卓机上 4G 内存跑 alpaca,欢迎试用轻量级 LLM 模型推理框架 InferLLM
从 LLM 火爆以来,社区已经出现了非常多优秀的模型,当然他们最大的特点就是体积大,最近为了让大模型可以在更低端的设备上运行,社区做了非常多的工作, gptq 实现了将模型进行低比特量化,因此降低了运 ...
- RestTemplate发送get请求并携带请求头
//设置请求头 HttpHeaders headers = new HttpHeaders(); headers.add("X-Access-Token", huaWenToken ...
- 2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边 edges一定表示的是一个无环无向图,也
2022-11-04:给定一个正数n,表示有多少个节点 给定一个二维数组edges,表示所有无向边 edges[i] = {a, b} 表示a到b有一条无向边 edges一定表示的是一个无环无向图,也 ...
- 2022-07-05:给定一个数组,想随时查询任何范围上的最大值。 如果只是根据初始数组建立、并且以后没有修改, 那么RMQ方法比线段树方法好实现,时间复杂度O(N*logN),额外空间复杂度O(N*
2022-07-05:给定一个数组,想随时查询任何范围上的最大值. 如果只是根据初始数组建立.并且以后没有修改, 那么RMQ方法比线段树方法好实现,时间复杂度O(NlogN),额外空间复杂度O(Nlo ...
- 2022-04-12:给定一个字符串形式的数,比如“3421“或者“-8731“, 如果这个数不在-32768~32767范围上,那么返回“NODATA“, 如果这个数在-32768~32767范围上
2022-04-12:给定一个字符串形式的数,比如"3421"或者"-8731", 如果这个数不在-32768~32767范围上,那么返回"NODAT ...
- 2022-01-02:给定两个数组A和B,长度都是N, A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n), 你的目的是让A有序,返回你能不能做到。
2022-01-02:给定两个数组A和B,长度都是N, A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n), 你的目的是让A有序,返回你能不能做到. 答案2022- ...
- flask之数据模型flask-sqlalchemy
一.安装数据库连接依赖包 pip install flask-sqlalchemy pip install pymysql 二.项目配置 app/__init__.py from flask_sqla ...
- JDBC-Utils层的简单运用
项目中JDBC的Utils层运行需要以下六个步骤 //1.定义属性为空 private static String driver = null; private static String url = ...