gin数据解析,绑定和渲染

news2024/10/7 10:14:02

一. 数据解析和绑定

        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 main

import (
	"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 main

import (
	"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 main

import (
	"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 Login

		if 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 main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/testdata/protoexample"
)

func main() {
	r := gin.Default()

	//1. json
	r.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    string
			Message string
			Number  int
		}

		msg.Name = "root"
		msg.Message = "someStruct"
		msg.Number = 1
		c.JSON(http.StatusOK, msg)
	})

	//3. xml
	r.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 main

import (
	"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 main

import (
	"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中的define
		c.HTML(http.StatusOK, "user/index.html", gin.H{"title": "我是测试", "message": "123"})
	})
	r.Run()
}

演示:

  •  html头尾分离

代码:

package main

import (
	"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中的define
		c.HTML(http.StatusOK, "user/index.html", gin.H{"title": "我是测试", "message": "123"})
	})
	r.Run()
}

演示:

  •  如果你需要引入静态文件需要定义一个静态文件目录
r.Static("./assets", "./assets")

         2.3 重定向

  • 使用gin.Context的Redirect方法
package main

import (
	"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 main

import (
	"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()
}

        异步是启动一个协程去执行请求。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1879426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【从零开始学架构 架构基础】四 架构设计的复杂度来源:可扩展性复杂度来源

架构设计的复杂度来源其实就是架构设计要解决的问题&#xff0c;主要有如下几个&#xff1a;高性能、高可用、可扩展、低成本、安全、规模。复杂度的关键&#xff0c;就是新旧技术之间不是完全的替代关系&#xff0c;有交叉&#xff0c;有各自的特点&#xff0c;所以才需要具体…

Solidworke学习(装配体3)

目录 本节学习内容&#xff1a; 一、高级配合 &#xff08;1&#xff09;对称配合 &#xff08;2&#xff09;宽度配合 &#xff08;3&#xff09;距离配合 二、机械配合 &#xff08;1&#xff09;凸轮配合 &#xff08;2&#xff09;槽口配合 三、快捷菜单 本节学习…

折半查找详解

一&#xff1a;折半查找概念 折半查找&#xff08;也称为二分查找&#xff09;是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始&#xff0c;如果中间元素正好是目标值&#xff0c;则搜索过程结束&#xff1b;如果目标值大于或小于中间元素&#x…

Uniapp 默认demo安装到手机里启动只能看得到底tab无法看到加载内容解决方案

Uniapp 默认demo安装到手机里以后&#xff0c;启动APP只能看到底tab栏&#xff0c;无法看到每个tab页对应的内容&#xff0c;HBuilder会有一些这样的报错信息&#xff1a; Waiting to navigate to: /pages/tabBar/API/API, do not operate continuously: 解决方案&#xff1a;…

FastAPI教程III

本文参考FastAPI教程https://fastapi.tiangolo.com/zh/tutorial 这部分暂无需求的没有记录&#xff0c;仅放置标题。 依赖项 安全性 中间件 你可以向FastAPI应用添加中间件。 ”中间件“是一个函数&#xff0c;它在每个请求被特定的路径操作处理之前&#xff0c;以及在每个…

SpringBoot:使用Spring Batch实现批处理任务

引言 在企业级应用中&#xff0c;批处理任务是不可或缺的一部分。它们通常用于处理大量数据&#xff0c;如数据迁移、数据清洗、生成报告等。Spring Batch是Spring框架的一部分&#xff0c;专为批处理任务设计&#xff0c;提供了简化的配置和强大的功能。本文将介绍如何使用Spr…

cpu,缓存,辅存,主存之间的关系及特点

关系图 示意图&#xff1a; ------------------- | CPU | | ------------- | | | 寄存器 | | | ------------- | | | L1缓存 | | | ------------- | | | L2缓存 | | | ------------- | | | L3缓存 | | | ------------- | ----…

test——认识测试

目录 前言 一什么是测试 1测试场景 2为什么需要测试 3测试定义 二测试的岗位 1测开与测试 2测试与开发的区别 a工作内容 b难易程度 c其它不同 三测试人员具备的素质 1综合能力 a沟通能力 b快速学习能力 c开发能力 d文字能力 2掌握自动化测试技术 前言 互联⽹…

Python基于决策树分类模型、随机森林分类模型、KNN分类模型和GBDT分类模型完成收入预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 在全球化的今天&#xff0c;收入不平等已经成为各国政府和社会关注的焦点问题之一。了解居民收入状况&…

后端之路第三站(Mybatis)——XML文件操作sql

一、XML映射文件是啥 前面我们学过了在Mapper接口用注解的方式来操作sql语句 那么XML映射文件就另一种操作sql语句的方法 为什么还要有这么个玩意&#xff1f; 我简单说就是&#xff1a;如果有的sql特别复杂的话&#xff0c;比如需要【动态sql】的话&#xff0c;就得用到XM…

木各力“GERRI”被“GREE”格力无效宣告成功

近日“GERRI”被“GREE”格力无效宣告成功&#xff0c;“GERRI”和“GREE”近似不&#xff0c;如果很近似当初就不会通过初审和下商标注册证&#xff0c;但是如果涉及知名商标和驰名商标&#xff0c;人家就可以异议和无效。 “GERRI”在被无效宣告时&#xff0c;引用了6个相关的…

电子电路学习笔记(4)三极管

部分内容参考链接&#xff1a; 电子电路学习笔记&#xff08;5&#xff09;——三极管_三极管 箭头-CSDN博客 模拟电子技术基础笔记&#xff08;4&#xff09;——晶体三极管_集电结的单向导电性-CSDN博客 硬件基本功-36-三极管Ib电流如何控制Ic电流_哔哩哔哩_bilibili 部分…

算法入门(上)

什么是算法&#xff1f; 算法&#xff08;Algorithm&#xff09;是解决特定问题求解步骤的描述&#xff0c;在计算机中表现为指令的有限序列&#xff0c;并且每条指令表示一个或多个操作。 给定一个问题&#xff0c;能够解决这个问题的算法是有很多种的。算式中的问题是千奇百怪…

【SCAU操作系统】期末复习简答及计算题例题解析

目录 一、写出下列英文缩写词在计算机系统中的英文或中文全名。 二、进程状态/调度/周转问题 &#xff08;1&#xff09;进程状态 &#xff08;2&#xff09;进程状态转换 &#xff08;3&#xff09;进程调度 &#xff08;4&#xff09;最短进程优先调度算法 三、逻辑地…

扫描全能王的AI驱动创新与智能高清滤镜技术解析

目录 引言1、扫描全能王2、智能高清滤镜黑科技2.1、图像视觉矫正2.2、去干扰技术 3、实际应用案例3.1、打印文稿褶皱检测3.2、试卷擦除手写3.3、老旧文件处理3.4、收银小票3.5、从不同角度扫描文档 4、用户体验结论与未来展望 引言 在数字化时代背景下&#xff0c;文档扫描功能…

51单片机第17步_外部中断

本章重点学习外部中断。 1、外部中断0框图&#xff1a; 2、外部中断1框图&#xff1a; 3、Keil C51中有一些关键字&#xff0c;需要牢记&#xff1a; interrupt 0&#xff1a;指定当前函数为外部中断0&#xff1b; interrupt 1&#xff1a;指定当前函数为定时器0中断&#x…

【Spring Boot】认识 JPA 的接口

认识 JPA 的接口 1.JPA 接口 JpaRepository2.分页排序接口 PagingAndSortingRepository3.数据操作接口 CrudRepository4.分页接口 Pageable 和 Page5.排序类 Sort JPA 提供了操作数据库的接口。在开发过程中继承和使用这些接口&#xff0c;可简化现有的持久化开发工作。可以使 …

电路笔记(电源模块): 基于FT2232HL实现的jtag下载器硬件+jtag的通信引脚说明

JTAG接口说明 JTAG 接口根据需求可以选择20针或14针的配置&#xff0c;具体选择取决于应用场景和需要连接的功能。比如之前的可编程逻辑器件XC9572XL使用JTAG引脚&#xff08;TCK、TDI、TDO、TMS、VREF、GND&#xff09;用于与器件进行调试和编程通信。更详细的内容可以阅读11…

(超详细)数据结构——“栈”的深度解析

前言&#xff1a; 在前几章我们介绍了线性表的基本概念&#xff0c;也讲解了包括顺序表&#xff0c;单链表&#xff0c;双向链表等线性表&#xff0c;相信大家已经对线性表比较熟悉了&#xff0c;今天我们要实现线性表的另一种结构——栈。 1.栈的概念 栈&#xff1a;一种特殊…

AI是如何与快充技术结合的?

针对AI技术在快充领域的运用&#xff0c;我们可以进一步深入探讨AI如何与快充技术结合&#xff0c;提升充电效率和用户体验。以下是一些具体的AI技术在快充领域的应用场景&#xff1a; 一、智能充电算法 学习充电模式&#xff1a;AI算法可以学习用户的充电习惯&#xff0c;比…