gin数据解析,绑定和渲染
一. 数据解析和绑定
1.1 Json数据解析和绑定
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/loginForm" method="post"enctype="application/x-www-form-urlencoded">
用户名<input type="text" name="username"><br>
密码<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
代码:
- gin.Context中的ShouldBind方法将请求中的正文中的数据,自动按照json格式解析到结构体。
package mainimport ("net/http""github.com/gin-gonic/gin"
)// 定义接收数据的结构体
type Login struct {//binding:"required"修饰字段,若接收为空值,则报错Account string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`Passwd string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}func main() {//创建路由r := gin.Default()//设置HTML文件所在目录r.LoadHTMLGlob("./*.html")r.GET("/", func(c *gin.Context) {//发送html文件内容c.HTML(http.StatusOK, "index.html", nil)})r.POST("/loginForm", func(c *gin.Context) {//声明接收变量var json Login//将request的body中的数据,自动按照json格式解析到结构体if err := c.ShouldBindJson(&json); err != nil {//gin.H封装了生成json数据工具c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),})return}//判断用户名密码是否正确if json.Account != "root" || json.Passwd != "admin" {c.JSON(http.StatusBadRequest, gin.H{"status": ".304",})return}c.JSON(http.StatusOK, gin.H{"status": "ok",})})r.Run()
}
演示:

1.2. 表单数据解析和绑定
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/loginForm" method="post"enctype="application/x-www-form-urlencoded">
用户名<input type="text" name="username"><br>
密码<input type="password" name="password">
<input type="submit" value="提交">
</form>
</body>
</html>
代码:
- gin.Context的Bind方法默认解析并绑定form格式,根据请求头中的content-type自动推断。
package mainimport ("net/http""github.com/gin-gonic/gin"
)// 定义接收数据的结构体
type Login struct {//binding:"required"修饰字段,若接收为空值,则报错Account string `form:"username" binding:"required"`Passwd string `form:"password" binding:"required"`
}func main() {//创建路由r := gin.Default()//设置HTML文件所在目录r.LoadHTMLGlob("./*.html")r.GET("/", func(c *gin.Context) {//发送html文件内容c.HTML(http.StatusOK, "index.html", nil)})r.POST("/loginForm", func(c *gin.Context) {//声明接收变量var form Login//Bind()默认解析并绑定form格式//根据请求头中的content-type自动推断if err := c.Bind(&form); err != nil {//gin.H封装了生成json数据工具c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),})return}//判断用户名密码是否正确if form.Account != "root" || form.Passwd != "admin" {c.JSON(http.StatusBadRequest, gin.H{"status": ".304",})return}c.JSON(http.StatusOK, gin.H{"status": "ok",})})r.Run()
}
1.3. URI数据解析和绑定
- gin.Context中的ShouldBindUri方法将uri中的数据,自动按照uri格式解析到结构体。
package mainimport ("net/http""github.com/gin-gonic/gin"
)// 定义接收数据的结构体
type Login struct {//binding:"required"修饰字段,若接收为空值,则报错Account string `uri:"user" binding:"required"`Passwd string `uri:"password" binding:"required"`
}func main() {//创建路由r := gin.Default()r.GET("/:user/:password", func(c *gin.Context) {//声明接收变量var uri Loginif err := c.ShouldBindUri(&uri); err != nil {//gin.H封装了生成json数据工具c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(),})return}//判断用户名密码是否正确if uri.Account != "root" || uri.Passwd != "admin" {c.JSON(http.StatusBadRequest, gin.H{"status": ".304",})return}c.JSON(http.StatusOK, gin.H{"status": "ok",})})r.Run()
}
演示:


二. gin渲染
2.1 各种数据的响应
多种响应方式:
package mainimport ("net/http""github.com/gin-gonic/gin""github.com/gin-gonic/gin/testdata/protoexample"
)func main() {r := gin.Default()//1. jsonr.GET("/someJson", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "someJson","status": "ok",})})//2. 结构体响应r.GET("/someStruct", func(c *gin.Context) {var msg struct {Name stringMessage stringNumber int}msg.Name = "root"msg.Message = "someStruct"msg.Number = 1c.JSON(http.StatusOK, msg)})//3. xmlr.GET("/someXml", func(c *gin.Context) {c.XML(http.StatusOK, gin.H{"message": "abc"})})//4. YAML响应r.GET("/someYaml", func(c *gin.Context) {c.YAML(http.StatusOK, gin.H{"message": "123",})})//5. protobuf格式//构建一个自己的传输格式r.GET("/someProtobuf", func(c *gin.Context) {resp := []int64{int64(1), int64(2)}lable := "lable"data := &protoexample.Test{Label: &lable,Reps: resp,}c.ProtoBuf(http.StatusOK, data)})r.Run()
}
2.2 HTML模板渲染
- gin支持加载HTML模板,然后根据模板进行配置并返回相应的数据,本质就是字符串替换。
- LoadHTMLGlob()方法可以加载模板文件
目录结构:

html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{.title}}</title>
</head>
<body>
fgkjdskjdsh{{.ce}}
</body>
</html>
代码:
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.LoadHTMLGlob("./tem/*") //从运行文件位置开始 需要加载的html文件路径r.GET("/someHtml", func(c *gin.Context) {c.HTML(http.StatusOK, "index.html", nil)})r.Run()
}
- 当html的目录结构如下时

html:
{{ define "user/index.html" }}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>{{.title}}</title>
</head><body>fgkjdskjdsh{{.message}}</body>
</html>
{{ end }}
代码:
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.LoadHTMLGlob("tem/*/*") //从运行文件位置开始 需要加载的html文件路径r.GET("/someHtml", func(c *gin.Context) {//user/index.html为html中的definec.HTML(http.StatusOK, "user/index.html", gin.H{"title": "我是测试", "message": "123"})})r.Run()
}
演示:

- html头尾分离

代码:
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.LoadHTMLGlob("tem/*/*") //从运行文件位置开始 需要加载的html文件路径r.GET("/someHtml", func(c *gin.Context) {//user/index.html为html中的definec.HTML(http.StatusOK, "user/index.html", gin.H{"title": "我是测试", "message": "123"})})r.Run()
}
演示:

- 如果你需要引入静态文件需要定义一个静态文件目录
r.Static("./assets", "./assets")
2.3 重定向
- 使用gin.Context的Redirect方法
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/index", func(c *gin.Context) {//重定向c.Redirect(http.StatusMovedPermanently, "redirect")})r.GET("/redirect", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "hello",})})r.Run()
}

2.4 同步异步
- goroutine机制可以方便地实现异步处理
- 另外,在启动新的goroutine时,不应该使用原始上下文context,必须使用它的只读副本
package mainimport ("log""time""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/long_async", func(c *gin.Context) {//上下文副本c_tmp := c.Copy()//异步处理go func() {time.Sleep(2 * time.Second)log.Println("异步执行 " + c_tmp.Request.URL.Path)}()})r.GET("/long_sync", func(c *gin.Context) {time.Sleep(3 * time.Second)log.Println("同步执行 " + c.Request.URL.Path)})r.Run()
}
异步是启动一个协程去执行请求。

相关文章:
gin数据解析,绑定和渲染
一. 数据解析和绑定 1.1 Json数据解析和绑定 html文件: <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...
Django 对模型创建的两表插入数据
1,添加模型 Test/app8/models.py from django.db import modelsclass User(models.Model):username models.CharField(max_length50, uniqueTrue)email models.EmailField(uniqueTrue)password models.CharField(max_length128) # 使用哈希存储密码first_name …...
Lua: 轻量级多用途脚本语言
Lua 是一种高效而轻量级的脚本语言,具备强大的扩展性和灵活性,广泛应用于游戏开发、嵌入式系统、Web 应用等多个领域。本文将深入探讨 Lua 的特性、应用场景以及如何使用 Lua 进行开发。 1. Lua 的起源与发展 Lua 的发展始于上世纪90年代初,…...
PotPlayer安装及高分辨率设置
第1步: 下载安装PotPlayer软件 PotPlayer链接:https://pan.baidu.com/s/1hW168dJrLBonUnpLI6F3qQ 提取码:z8xd 第2步: 下载插件,选择系统对应的位数进行运行,该文件不能删除,删除后将失效。 …...
实现写入缓存策略的最佳方法探讨
实现写入缓存策略的最佳方法探讨 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在软件开发中实现写入缓存策略的最佳方法。缓存在提升应用性能和…...
【Day03】0基础微信小程序入门-学习笔记
文章目录 视图与逻辑学习目标页面导航1. 声明式导航2. 编程式导航3. 导航传参 页面事件1. 下拉刷新2. 上拉触底3.扩展-自定义编译模式 生命周期1. 简介2. 生命周期函数3. 应用的生命周期函数4. 页面生命周期函数 WXS脚本1. 概述2. 基础语法3. WXS的特点4. 使用WXS处理手机号 总…...
libctk shared library的设计及编码实践记录
一、引言 1.1 <libctk>的由来 1.2 <libctk>的设计理论依据 1.3 <libctk>的设计理念 二、<libctk>的依赖库 三、<libctk>的目录说明 四、<libctk>的功能模块及使用实例说明 4.1 日志模块 4.2 mysql client模块 4.3 ftp client模块 4…...
【代码随想录训练营】【Day 65】【图论-2】| 卡码 99
【代码随想录训练营】【Day 65】【图论-2】| 卡码 99 需强化知识点 深度搜索和广度搜索 题目 99. 岛屿数量 思想:遍历到为1的节点,再搜索标记,每遇到新的陆地节点,增加计数 深度搜索广度搜索:此处用 [] 作为待遍…...
【动态规划】139. 单词拆分
139. 单词拆分 难度:中等 力扣地址:https://leetcode.cn/problems/word-break/description/ 问题描述 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字…...
【C++】空指针访问成员函数
空指针访问成员函数 C中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针 如果用到this指针,需要加以判断保证代码的健壮性 class Animal { public:void fun1() {//正常的成员函数}void fun2() {if (this NULL) {return;//如果没有这个…...
Linux的IO易错点总结
本文主要记录IO的一些易错操作。 阻塞IO和非阻塞IO,一般都是针对数据读取的,因为write是主动行为,不存在阻塞这一说。 非阻塞式IO,一般都要配合while轮询来读取数据。 IO多路复用 当只检测一路IO的时候,和普通IO的作…...
【Android面试八股文】说一说你对Android中的Context的理解吧
文章目录 一、Context是什么?1.1 主要功能和用途1.2 如何获取 Context 实例?1.3 注意事项二、Context 类的层次结构三、Context的数量四、Context的注意事项五、Android 中有多少类型的 Context,它们有什么区别 ?六、Contextlmpl实例是什么时候生成的,在 Activity 的 oncr…...
AI在音乐创作中的角色:创造还是毁灭?
目录 一、基本情况介绍 二、近期新闻 三、AI生成音乐方面的商业模式 四、人工智能和音乐人可能的合作模式 五、人们如何借助AI来创作音乐 六、人工智能在创意产业引发的伦理道德问题 七、如何平衡技术发展与提高人类创造积极性的关系? 总结 一、基本情况介绍…...
[深入理解DDR] 总目录
依公知及经验整理,原创保护,禁止转载。 专栏 《深入理解DDR》 蓝色的是传送门,点击链接即可到达指定文章。 图。 DDR 分类 导论 [RAM] DRAM 导论:DDR4 | DDR5 | LPDDR5 | GDRR6 | HBM 应运而生 运存与内存?内存与存…...
模板方法模式在金融业务中的应用及其框架实现
引言 模板方法模式(Template Method Pattern)是一种行为设计模式,它在一个方法中定义一个算法的框架,而将一些步骤的实现延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。在金融业务中ÿ…...
leetcode347.前k个高频元素
leetcode347.前k个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 示例 2: 输入: nums [1], k 1 输出: [1] 优先队列法 struct hash_…...
c++(二)
1. 类和对象 1.1. 封装 封装的意义 将属性和行为作为一个整体,表现生活中的事物;将属性和行为加以权限控制 public -> 公共权限:类内可以访问,类外也可以访问protected -> 保护权限:类内可以访问,…...
基于PHP的初中数学题库管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的初中数学题库管理系统 一 介绍 此初中数学题库管理系统基于原生PHP开发,数据库mysql,系统角色分为学生,教师和管理员。(附带参考设计文档) 技术栈:phpmysqlphpstudyvscode 二 功能 …...
WDG看门狗
1 WDG 1.1 简介 WDG是看门狗定时器(Watchdog Timer)的缩写,它是一种用于计算机和嵌入式系统中的定时器,用来检测和恢复系统故障。 看门狗就像是一个忠诚的宠物狗,它时刻盯着你的程序,确保它们正常运行。…...
zabbix server client 安装配置
Zabbix Server 采用源码包部署,数据库采用 MySQL8.0 版本,zabbix-web 使用 nginxphp 来实现。具体信息如下: 软件名 版本 安装方式 Zabbix Server 6.0.3 源码安装 Zabbix Agent 6.0.3 源码安装 MySQL 8.0.28 yum安装 Nginx 1.20…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
