数据解析和绑定

json数据解析和绑定
package main

import (
"github.com/gin-gonic/gin"
"net/http"
) // 定义接受数据的结构体
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// JSON绑定
r.POST("loginJSON", 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.User != "root" || json.Pssword != "admin" {
c.JSON(http.StatusBadRequest, gin.H{"status": "304"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "200"})
})
r.Run()
} /*
curl http://127.0.0.1:8080/loginJSON -H 'content-type:application/json' -d "{\"user\":\"root\",\"password\":\"admin\"}" -X POST {"status":"200"}%
*/

表单数据解析和绑定

gin_demo1.go

package main

import (
"github.com/gin-gonic/gin"
"net/http"
) // 定义接受数据的结构体
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() // JSON绑定
r.POST("/loginFrom", func(c *gin.Context) {
// 声明接受的变量
var form Login
if err := c.Bind(&form); err != nil {
c.JSON(http.StatusBadRequest,gin.H{"error": err.Error()})
return
} // 判断用户名密码是否正确
if form.User != "root" || form.Pssword != "admin" {
c.JSON(http.StatusBadRequest,gin.H{"status":"304"})
return
} c.JSON(http.StatusOK,gin.H{"status":"200"})
}) r.Run()
}

login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="http://127.0.0.1:8080/loginFrom" method="post" enctype="multipart/form-data">
用户名: <input type="text" name="username">
密码: <input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
URL数据解析和绑定

gin_demo1.go

package main

import (
"github.com/gin-gonic/gin"
"net/http"
) // 定义接受数据的结构体
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() // JSON绑定
r.GET("/:user/:password", func(c *gin.Context) {
// 声明接受的变量 var login Login
if err := c.ShouldBindUri(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} if login.User != "root" || login.Pssword != "admin" {
c.JSON(http.StatusBadRequest,gin.H{"status":"304"})
return
} c.JSON(http.StatusOK,gin.H{"status":"200"})
}) r.Run()
} /*
curl http://127.0.0.1:8080/root/admin
{"status":"200"}%
*/

Gin渲染

各种数据格式的响应

json,结构体,xml, yaml类似于java的properties,protobuf

package main

import (
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/testdata/protoexample"
) // 定义接受数据的结构体
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 1. JSON绑定
r.GET("/someJSON", func(c *gin.Context) {
c.JSON(200,gin.H{"message":"someJSON","status":200})
}) // 2. 结构体响应
r.GET("/someStruct", func(c *gin.Context) {
var msg struct{
Name string
Message string
Number int
} msg.Name = "root"
msg.Message = "message"
msg.Number = 123
c.JSON(200,msg)
}) // 3. XML
r.GET("/someXML", func(c *gin.Context) {
c.XML(200,gin.H{"message":"abc"})
}) // 4. YAML
r.GET("/someYAML", func(c *gin.Context) {
c.YAML(200,gin.H{"name":"youmen"})
}) // 5.protobuf格式,谷歌开发的高效存储读取的工具
// 数组?切片?如果自己构建一个传输格式,应该是什么格式? r.GET("/someProtoBuf", func(c *gin.Context) {
reps := []int64{int64(1),int64(2)} // 定义数据
label := "label" // 传protobuf格式数据
data := &protoexample.Test{
Label: &label,
Reps: reps,
}
c.ProtoBuf(200,data)
}) r.Run()
}
HTML模板渲染

gin支持加载HTML模板,然后根据模板参数进行配置并返回相应的数据,本质上就是字符串替换.

LoadHTMLGlob()方法可以加载配置文件

HTML渲染

gin_demo1.go

package main

import (
"github.com/gin-gonic/gin"
) // 定义接受数据的结构体
type Login struct {
// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
User string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() // 加载配置文件
r.LoadHTMLGlob("templates/*") r.GET("/index", func(c *gin.Context) {
// 根据文件名渲染
// 最终json将title替换
c.HTML(200,"index.tmpl",gin.H{"title":"我的标题"})
}) r.Run()
}

index.tmpl

<html>
<h1>
{{ .title }}
</h1>
</html>

重定向

package main

import (
"github.com/gin-gonic/gin"
"net/http"
) func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() r.GET("/index", func(c *gin.Context) {
// 支持内部和外部重定向
c.Redirect(http.StatusMovedPermanently,"http://www.baidu.com/")
})
r.Run()
}

同步异步

goroutine机制可以方便地实现异步处理

另外,在启动新的goroutine时,不应该使用原始上下文,必须使用它的只读副本

package main

import (
"github.com/gin-gonic/gin"
"log"
"time"
) func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() // 1. 异步
r.GET("/long_async", func(c *gin.Context) {
// 需要搞一个副本
copyContext := c.Copy() // 异步处理
go func() {
time.Sleep(3 * time.Second)
log.Println("异步执行:" + copyContext.Request.URL.Path)
}()
}) // 2. 同步
r.GET("/long_sync", func(c *gin.Context) {
time.Sleep(3 * time.Second)
log.Println("同步执行:" + c.Request.URL.Path)
}) r.Run()
}

Gin中间件

所有请求都经过中间件

gin可以构建中间件,但它只对注册过的路由函数起作用

对于分组路由,嵌套使用中间件,可以限定中间件的作用范围

中间件分为全局中间件,单个路由中间件和群组中间件

gin中间件必须是一个 gin.HandlerFunc 类型

全局中间件

middleware.go

package main

import (
"fmt"
"github.com/gin-gonic/gin"
"time"
) // 定义中间件
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中, 可以通过Get()取
c.Set("request","中间件")
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
status := c.Writer.Status()
fmt.Println("中间件执行完毕",status)
t2 := time.Since(t)
fmt.Println("time:",t2)
}
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 注册中间件
r.Use(MiddleWare())
// 为了代码规范
{
r.GET("/middleware", func(c *gin.Context) {
// 取值
req, _:=c.Get("request")
fmt.Println("request",req)
// 页面接受
c.JSON(200,gin.H{"request":req})
})
}
r.Run()
} /*
curl localhost:8080/middleware
{"request":"中间件"}%
*/

局部中间件

package main

import (
"fmt"
"github.com/gin-gonic/gin"
"time"
) // 定义中间件
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中, 可以通过Get()取
c.Set("request","中间件")
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
status := c.Writer.Status()
fmt.Println("中间件执行完毕",status)
t2 := time.Since(t)
fmt.Println("time:",t2)
}
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 注册中间件
r.Use(MiddleWare())
// 为了代码规范
{
r.GET("/middleware",MiddleWare(),func(c *gin.Context) {
// 取值
req, _:=c.Get("request")
fmt.Println("request",req)
// 页面接受
c.JSON(200,gin.H{"request":req})
})
}
r.Run()
}

Example1

package main

import (
"fmt"
"github.com/gin-gonic/gin"
"time"
) // 定义中间
func myTime(c *gin.Context) {
start := time.Now()
c.Next() // 统计时间
since := time.Since(start)
fmt.Println("程序耗时",since)
} func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default() // 注册中间件
r.Use(myTime) // {}为了代码规范
shoppingGroup := r.Group("/shopping")
{
shoppingGroup.GET("/index",shopIndexHandler)
shoppingGroup.GET("/home",shopHomeHandleer)
} r.Run()
} func shopIndexHandler(c *gin.Context) {
time.Sleep(5 * time.Second)
} func shopHomeHandleer(c *gin.Context) {
time.Sleep(5 * time.Second)
}

02 . Go框架之Gin框架从入门到熟悉(数据解析和绑定,渲染,重定向,同步异步,中间件)的更多相关文章

  1. gin框架中的数据解析与绑定

    Json数据解析与绑定 客户端传参,后端接收并解析到结构体 func Login(context *gin.Context) { // 声明接收的变量 var login LoginJson // 将 ...

  2. 01 . Go框架之Gin框架从入门到熟悉(路由和上传文件)

    Gin框架简介 Gin是使用Go/Golang语言实现的HTTP Web框架, 接口简洁, 性能极高,截止1.4.0版本,包含测试代码,仅14K, 其中测试代码9K, 也就是说测试源码仅5k左右, 具 ...

  3. Go语言基础之20--web编程框架之Gin框架

    一.Gin框架介绍 1.1 简介 A. 基于httprouter开发的web框架. http://github.com/julienschmidt/httprouter B. 提供Martini风格的 ...

  4. 03 . Go框架之Gin框架从入门到熟悉(Cookie和Session,数据库操作)

    Cookie Cookie是什么 HTTP是无状态协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否由同一个客户端发出 Cookie就是解决HTTP协议无状态的方案之一,中文是小 ...

  5. WPF快速入门系列(4)——深入解析WPF绑定

    一.引言 WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能.WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信 ...

  6. React入门---事件与数据的双向绑定-9

    上一节中,我们是从父组件给子组件传送数据,要实现事件与数据的双向绑定,我们来看如何从子组件向父组件传送数据; 接触之前,我们看一些里面函数绑定的知识: 例:通过点击事件改变state的age属性值: ...

  7. Web框架之Gin

    Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ...

  8. Gin框架介绍及使用

    Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ...

  9. Web框架之Gin介绍及使用

    Gin是一个用Go语言编写的web框架.它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍. 如果你是性能和高效的追求者, 你会爱上Gin. ...

随机推荐

  1. 一文了解.Net Core 3.1 Web API基础知识

    一.前言 随着近几年前后端分离.微服务等模式的兴起,.Net Core也似有如火如荼之势 ,自16年发布第一个版本到19年底的3.1 LTS版本,以及将发布的.NET 5,.NET Core一路更迭, ...

  2. 图片压缩工具pngquant

    关于图片压缩的,之前看到一个imageOptim,用着不错,也挺好用的,直接打开要压缩的图片或者文件夹,唰唰唰的就开始压缩了,如下图 后来觉得不是很方面,还要打开软件,选择文件夹,然后就又研究了一下, ...

  3. GitBook 3.2.3入门

    简介 GitBook 是一个基于 Node.js 的命令行工具,可使用 GitHub / Git.Markdown.AsciiDoc来制作精美的电子书.GitBook 可以将文档作为静态网站或电子书( ...

  4. Python练习题 019:求分数序列之和

    [Python练习题 019] 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和. --------------------------------- ...

  5. C语言中i++和++i的区别

    这一篇更详细: 转载:https://blog.csdn.net/Bug_fuck/article/details/85229229 C语言中++i和i++是有区别的!快速理解的话就是用一句话概括:1 ...

  6. JavaScript DOM三种创建元素的方式

    三种创建元素的方式: document.write() element.innerHTML document.createElement() 初始HTML内容: <button>btn&l ...

  7. 【Flutter Widgets大全】电子书开源

    [Flutter Widgets大全]是老孟耗费大量精力整理的,总共有330多个组件的详细用法,开源到Github上,希望可以帮助到大家,开源不易,点个赞可不可以. [Flutter Widgets ...

  8. 小程序将base64的多张图片,传到tp5后台

    zhu要是前端传过来的数据是base64的数据库存储不了base64的数据,因存储量太过于大,因此后台要将base64的数据转换成,34124323534.jpg等格式的,数据库才可将其存储 源码暂时 ...

  9. 微服务通信之feign集成负载均衡

    前言 书接上文,feign接口是如何注册到容器想必已然清楚,现在我们着重关心一个问题,feign调用服务的时候是如何抉择的?上一篇主要是从读源码的角度入手,后续将会逐步从软件构架方面进行剖析. 一.R ...

  10. 多测师讲解 _接口自动化框架设计分层思想(001)_高级讲师肖sir

    第一层: 第二层:调用接口层 VOQGWBZYNBOAVZGE