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

gin 基本使用

gin 初体验

import ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",})})r.Run()
}

gin 路由接受一个 type HandlerFunc func(Context) 类型的函数

New 和 Default 的区别

gin.New 和 gin.Default 都可以创建一个类型为 *gin.Engine 的 router

他们的区别是,gin.Default 加了两个中间件:Logger(), Recovery()

路由分组

路由分组功能是将相同功能的路由进行分组,方便管理

r := gin.Default()
r.GET("/goods/list", goodList)
r.GET("/goods/1", goodDetail)
r.POST("goods/add", createGood)
func goodList(c *gin.Context)   {}
func goodDetail(c *gin.Context) {}
func createGood(c *gin.Context) {}
r := gin.Default()
goodsGroup := r.Group("/goods")
{goodsGroup.GET("/list", goodList)goodsGroup.GET("/1", goodDetail)goodsGroup.POST("/add", createGood)
}

url 中的变量

要获取 url 中的变量,使用 :xxx 的形式

func main() {r := gin.Default()goodsGroup := r.Group("/goods"){goodsGroup.GET("/:id", goodDetail)}r.Run()
}func goodDetail(c *gin.Context) {id := c.Param("id")c.JSON(http.StatusOK, gin.H{"message": "id: " + id,})
}

这种形式会有一个问题,如果有两个路由,一个是 /goods/list,一个是 /goods/:id,那么 /goods/list 会被 /goods/:id 匹配到
解决办法是使用 goodsGroup.GET(“/list”, goodList),这样就不会有问题了

func main() {r := gin.Default()goodsGroup := r.Group("/goods"){goodsGroup.GET("/list", goodList)goodsGroup.GET("/:id", goodDetail)}r.Run()
}func goodList(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "list",})
}func goodDetail(c *gin.Context) {id := c.Param("id")c.JSON(http.StatusOK, gin.H{"message": "id: " + id,})
}

但是其他路由还是会进入到 /goods/:id 中,比如 /goods/detail

如果只想匹配 id 是数字,需要这样做

通过一个结构体来绑定 uri 中的参数,在注册函数中使用 ShouldBindUri 方法来绑定,如果不是绑定的类型,就返回错误

type Params struct {ID int `uri:"id" binding:"required"`
}func main() {r := gin.Default()goodsGroup := r.Group("/goods"){goodsGroup.GET("/:id", goodDetail)}r.Run()
}
func goodDetail(c *gin.Context) {id := c.Param("id")var params Paramsif err := c.ShouldBindUri(&params); err != nil {c.Status(http.StatusBadRequest)return}c.JSON(http.StatusOK, gin.H{"message": "id: " + id,})
}

还有一种形式是使用 * 来匹配,比如 /goods/*name

如果访问的路由是 /goods/1/2/3/4,那么 id 就是 1,name 就是 /2/3/4,一般用来访问服务器上的文件

goodsGroup.GET("/:id/*name", goodPersoon)
func goodPerson(c *gin.Context) {id := c.Param("id")name := c.Param("name")c.JSON(http.StatusOK, gin.H{"id": id,"name": name,})
}

获取请求中的参数

获取 query 参数,可以使用 c.Query(“key”),如果没有这个参数,就返回空字符串

如果想要获取 query 参数,但是没有这个参数,就返回默认值,可以使用 c.DefaultQuery(“key”, “default”)

page := c.DefaultQuery("page", "1")
size := c.Query("size")

获取 body 参数,可以使用 c.PostForm(“key”),如果没有这个参数,就返回空字符串
如果想要获取 body 参数,但是没有这个参数,就返回默认值,可以使用 c.DefaultPostForm(“key”, “default”)

name := c.DefaultPostForm("name", "default")
age := c.PostForm("age")

PostForm 是针对 Content-Type 是 application/x-www-form-urlencoded 和 application/form-data 的情况
如果请求参数是 application/json,那么需要使用 c.ShouldBindJSON/c.BindJSON 方法来获取参数

type Body struct {Name string `json:"name"`Age  int    `json:"age"`
}func goodAdd(c *gin.Context) {var body Bodyc.BindJSON(&body)c.JSON(http.StatusOK, gin.H{"name": body.Name,"age":  body.Age,})
}

表单验证

表单验证可以直接使用 binding 标签来实现

gin 内置了 validator,文档:validator

注册时,需要输入两次密码,可以使用 eqfield 来验证两次密码是否一致

type SignUpForm struct {Age        uint8  `json:"age" binding:"required,gte=1,lte=130"`Name       string `json:"name" binding:"required,min=3"`Email      string `json:"email" binding:"required,email"`Password   string `json:"password" binding:"required"`RePassword string `json:"re_password" binding:"required,eqfield=Password"`
}
r.POST("/signup", func(c *gin.Context) {var signUpFrom SignUpFormif err := c.ShouldBindJSON(&signUpFrom); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),})return}c.JSON(http.StatusOK, gin.H{"message": "ok",})
})

相关文章:

gin 基本使用

gin 初体验 import ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",})})r.Run() }gin 路由接受一个 type …...

8月最新修正版风车IM即时聊天通讯源码+搭建教程

8月最新修正版风车IM即时聊天通讯源码搭建教程。风车 IM没啥好说的很多人在找,IM的天花板了,知道的在找的都知道它的价值,开版好像就要29999,后端加密已解,可自己再加密,可反编译出后端项目源码,已增加启动后端需要google auth双重验证,pc端 web端 wap端 android端 ios端 都有 …...

NSDT孪生场景编辑器系统介绍

一、产品背景 数字孪生的建设流程涉及建模、美术、程序、仿真等多种人才的协同作业,人力要求高,实施成本高,建设周期长。如何让小型团队甚至一个人就可以完成数字孪生的开发,是数字孪生工具链要解决的重要问题。考虑到数字孪生复杂…...

3D WEB轻量化引擎HOOPS助力3D测量应用蓬勃发展:效率、精度显著提升

在3D开发工具领域,Tech Soft 3D打造的HOOPS SDK已经崭露头角,成为了全球领先的3D领域开发工具提供商。HOOPS SDK包括四种不同的3D软件开发工具,已成为行业的翘楚。 其中,HOOPS Exchange以其CAD数据转换的能力脱颖而出&#xff0c…...

【Orange Pi】Orange Pi5 Plus 安装记录

官网:Orange Pi - Orangepi 主控芯片:Rockchip RK3588(8nm LP制程)NPU:内嵌的 NPU 支持INT4/INT8/INT16/FP16混合运算,算力高达 6Top支持的操作系统: Orangepi OS(Droid)Orangepi O…...

NLP 项目:维基百科文章爬虫和分类 - 语料库阅读器

塞巴斯蒂安 一、说明 自然语言处理是机器学习和人工智能的一个迷人领域。这篇博客文章启动了一个具体的 NLP 项目,涉及使用维基百科文章进行聚类、分类和知识提取。灵感和一般方法源自《Applied Text Analysis with Python》一书。 在接下来的文章中,我将…...

查看吾托帮88.47的docker里的tomcat日志

步骤如下 (1)ssh (2)ssh root192.168.88.47 等待输入密码:fytest (3)pwd #注释:输出/root (4)docker exec -it wetoband_deploy /bin/bash #注释&#xff1…...

衷心 祝愿

达之云衷心祝愿您,中秋国庆双节快乐,阖家幸福!感谢您们一直以来对达之云的关注与支持。 双节来临之际,达之云发布全新产品——达之云CDP客户数据平台(Dazdata CDP),致力于为中小企业提供互联网营…...

表单中某一项点击添加和删除

<!-- 特殊表单 --><div v-for"(item, index) in form.fwzb" :key"indexfwzb" style"height: 102px"><el-form-item label"经度&#xff1a;" class"form-style":prop"fwzb. index .lon":rules&q…...

深信服安全GPT 2.0升级,开启安全运营“智能驾驶”旅程

9月22日&#xff0c;深信服对外展示安全GPT落地成果与2.0升级能力。来自各行业权威嘉宾代表&#xff1a;美的集团首席信息安全官&#xff08;CISO&#xff09;兼软件工程院院长、欧洲科学院院士&#xff08;MAE&#xff09;、IEEE Fellow、IET Fellow、ACM杰出科学家、AAIA Fel…...

【C++】STL之list深度剖析及模拟实现

目录 前言 一、list 的使用 1、构造函数 2、迭代器 3、增删查改 4、其他函数使用 二、list 的模拟实现 1、节点的创建 2、push_back 和 push_front 3、普通迭代器 4、const 迭代器 5、增删查改(insert、erase、pop_back、pop_front) 6、构造函数和析构函数 6.1、默认构造…...

解释器风格架构C# 代码

/*解释器风格架构是一种基于组件的设计架构&#xff0c;它将应用程序分解为一系列组件&#xff0c;每个组件负责处理特定的任务。这种架构有助于提高代码的可维护性和可扩展性。以下是如何使用C#实现解释器风格架构的步骤&#xff1a;定义组件&#xff1a;首先&#xff0c;定义…...

第七天:gec6818开发板QT和Ubuntu中QT安装连接sqlite3数据库驱动环境保姆教程

sqlite3数据库简介 帮助文档 SQL Programming 大多数关系型数的操作步骤&#xff1a;1&#xff09;连接数据库 多数关系型数据库都是C/S模型 (Client/Server)sqlite3是一个本地的单文件关系型数据库&#xff0c;同样也有“连接”的过程 2&#xff09;操作数据库 作为程序员&am…...

自制网页。

文章目录 注:代码中图片等素材均来自网络,侵删 20230920_213831 index.html <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-…...

MySQL单表查询和多表查询

一、单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作等 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10)…...

蓝桥等考Python组别四级006

第一部分:选择题 1、Python L4 (15分) 在Python中,符号“\n”代表( )。 换行空格退格注释正确答案:A 2、Python L4 (15分) 已知大写字母A的ASCII码值为…...

第3章-指标体系与数据可视化-3.2-描述性统计分析与绘图

目录 3.2.1 描述性统计进行数据探索 1. 变量度量类型与分布类型 度量类型 分布类型...

更直观地学习 Git 命令

前言 本文参考于 Learn Git Branching 这个有趣的 Git 学习网站。 在该网站&#xff0c;可以使用 show command 命令展示所有可用命令。 直接访问网站的sandbox。 本地篇 基础篇 git commit git commit将暂存区的修改提交到本地版本库并创建一个新的提交&#xff0c;新提…...

在 Vue 项目中添加字典翻译工具(二)

封装字段翻译组件&#xff0c;可以格式化字典、枚举、字段 优点&#xff1a; 使用简单&#xff0c;一次配置多次使用&#xff0c;缓存降低后端请求次数&#xff0c;扩展性强 没有缓存时造成单页面多次请求解决方法&#xff1a;axios添加缓存请求&#xff0c;防止多次请求&#…...

RDMA Shared Receive Queue(四)

参考知乎文章《RDMA之Shared Receive Queue》&#xff1a;https://zhuanlan.zhihu.com/p/279904125 SRQ SRQ全称为Shared Receive Queue&#xff0c;即共享接受队列。在QP中&#xff0c;SQ用于下发SEND/WRITE/READ等操作&#xff0c;而RQ只用于下发RECV操作&#xff0c;对于本…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...