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…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
Spring事务传播机制有哪些?
导语: Spring事务传播机制是后端面试中的必考知识点,特别容易出现在“项目细节挖掘”阶段。面试官通过它来判断你是否真正理解事务控制的本质与异常传播机制。本文将从实战与源码角度出发,全面剖析Spring事务传播机制,帮助你答得有…...
