建网站专用网站/百度app下载链接

建网站专用网站,百度app下载链接,海口招商建设有限公司网站,网络营销建设网站实训【Go学习】04-1-Gin框架 初识框架go流行的web框架GinirisBeegofiber Gin介绍Gin快速入门 路由RESTful API规范请求方法URI静态url路径参数模糊匹配 处理函数分组路由 请求参数GET请求参数普通参数数组参数map参数 POST请求参数表单参数JSON参数 路径参数文件参数 响应字符串方式…

【Go学习】04-1-Gin框架

  • 初识框架
    • go流行的web框架
      • Gin
      • iris
      • Beego
      • fiber
    • Gin介绍
    • Gin快速入门
  • 路由
    • RESTful API规范
    • 请求方法
    • URI
      • 静态url
      • 路径参数
      • 模糊匹配
    • 处理函数
    • 分组路由
  • 请求参数
    • GET请求参数
      • 普通参数
      • 数组参数
      • map参数
    • POST请求参数
      • 表单参数
      • JSON参数
    • 路径参数
    • 文件参数
  • 响应
    • 字符串方式
    • JSON方式
    • XML方式
    • 文件方式
    • 设置http响应头
    • 重定向
    • YAML方式


初识框架

框架是一系列工具的集合,能让开发变的便捷。

学习框架的目的就是为了提供项目的开发效率,使我们更加专注业务,而不是和业务无关的底层代码。

go流行的web框架

如果学习过其他语言,可能知道Java用的比较多的是Spring框架,PHP用的比较多的是Laravel,python用的多的是Django,都在各自的语言中具有强大的统治力。

go从诞生之初就带有浓重的开源属性,其原生库已经很强大,即使不依赖框架,也能进行高性能开发,又因为其语言并没有一定的设计标准,所以较为灵活,也就诞生了众多的框架,各具有特色,满足不同的喜好。

Gin

地址:https://github.com/gin-gonic/gin

号称最快的go语言web框架,目前是go官方的推荐框架(https://go.dev/doc/tutorial/)。

iris

地址:https://github.com/kataras/iris

性能比gin高一些,支持MVC,但这款框架评价不太好,使用上问题较多,近些年很少去选择使用

Beego

地址:https://github.com/beego/beego

国人开发,最早的go web框架之一,工具集比较完善,性能较差,据传言作者是php转行,所以框架带有浓厚的php特色,早期国内使用的多,目前少有人选择。

fiber

地址:https://github.com/gofiber/fiber

2020年发布的框架,发展迅速,建立在fasthttp之上,性能目前最高,受Express启发,比较简洁,上手较快,和gin类似。

当然还有其他一些框架,但从star数上,以及流行程度上看,gin一骑绝尘,gin的好处在于其简洁,扩展性,稳定性以及性能都比较出色。

go的框架其实是可以理解为库,并不是用了某一个框架就不能用别的框架,可以选择性的使用各个库中的优秀组件,进行组合

Gin介绍

特性:

  • 快速

    基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。

  • 支持中间件

    传入的 HTTP 请求可以由一系列中间件和最终操作来处理。 例如:Logger,Authorization,GZIP,最终操作 DB。

  • Crash 处理

    Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!

  • JSON 验证

    Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。

  • 路由组

    更好地组织路由。是否需要授权,不同的 API 版本…… 此外,这些组可以无限制地嵌套而不会降低性能。

  • 错误管理

    Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。

  • 内置渲染

    Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。

  • 可扩展性

    新建一个中间件非常简单。

Gin快速入门

go版本需求:go1.13及以上

环境:windows 11

# 创建工作区
F:\Code\Golang\TuLing\workPath>mkdir ginlearn
F:\Code\Golang\TuLing\workPath>cd ginlearn
# 初始化工作区
F:\Code\Golang\TuLing\workPath\ginlearn>go work init# 创建模块
F:\Code\Golang\TuLing\workPath\ginlearn>mkdir helloworld
F:\Code\Golang\TuLing\workPath\ginlearn>cd helloworld
# 初始化模块
F:\Code\Golang\TuLing\workPath\ginlearn\helloworld>go mod init test.com/helloworld
go: creating new go.mod: module test.com/helloworld
F:\Code\Golang\TuLing\workPath\ginlearn\helloworld>cd ..# 将模块加入工作区
F:\Code\Golang\TuLing\workPath\ginlearn>go work use ./helloworld

使用goland打开

在这里插入图片描述

下载gin

PS F:\Code\Golang\TuLing\workPath\ginlearn> cd .\helloworld\
PS F:\Code\Golang\TuLing\workPath\ginlearn\helloworld> go get -u github.com/gin-gonic/gin

示例程序,创建main.go

package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}

运行后,apifox进行测试

在这里插入图片描述

符合预期,这样简单的代码就实现了一个http的服务

路由

路由是URI到函数的映射。

一个URI含: http://localhost:8080/user/find?id=11

  • 协议,比如http,https等
  • ip端口或者域名,比如127.0.0.1:8080或者www.test.com
  • path,比如 /path
  • query,比如 ?query

同时访问的时候,还需要指明HTTP METHOD,比如

  • GET

    GET方法请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据.

  • POST

    POST方法用于将实体提交到指定的资源,通常会导致在服务器上的状态变化

  • HEAD

    HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体.

  • PUT

    PUT方法用请求有效载荷替换目标资源的所有当前表示

  • DELETE

    DELETE方法删除指定的资源

  • CONNECT

    CONNECT方法建立一个到由目标资源标识的服务器的隧道。

  • OPTIONS

    OPTIONS方法用于描述目标资源的通信选项。

  • TRACE

    TRACE方法沿着到目标资源的路径执行一个消息环回测试。

  • PATCH

    PATCH方法用于对资源应用部分修改。

使用的时候,应该尽量遵循其语义

RESTful API规范

RESTful API 的规范建议我们使用特定的HTTP方法来对服务器上的资源进行操作。

比如:

  1. GET,表示读取服务器上的资源
  2. POST,表示在服务器上创建资源
  3. PUT,表示更新或者替换服务器上的资源
  4. DELETE,表示删除服务器上的资源
  5. PATCH,表示更新/修改资源的一部分

请求方法

r.GET("/get", func(ctx *gin.Context) {ctx.JSON(200, "get")
})
r.POST("/post", func(ctx *gin.Context) {ctx.JSON(200, "post")
})
r.DELETE("/delete", func(ctx *gin.Context) {ctx.JSON(200, "delete")
})
r.PUT("/put", func(ctx *gin.Context) {ctx.JSON(200, "put")
})

如果想要支持所有:

r.Any("/any", func(ctx *gin.Context) {ctx.JSON(200, "any")
})

如果想要支持其中的几种:

r.GET("/hello", func(ctx *gin.Context) {//数组 map list 结构体ctx.JSON(200, gin.H{"name": "hello world",})
})
r.POST("/hello", func(ctx *gin.Context) {//数组 map list 结构体ctx.JSON(200, gin.H{"name": "hello world",})
})

URI

URI书写的时候,我们不需要关心scheme和authority这两部分,我们主要通过path和query两部分的书写来进行资源的定位。

静态url

比如/hello/user/find

r.POST("/user/find", func(ctx *gin.Context) {
})

路径参数

比如/user/find/:id

r.POST("/user/find/:id", func(ctx *gin.Context) {param := ctx.Param("id")ctx.JSON(200, param)
})

模糊匹配

比如/user/*path

r.POST("/user/*path", func(ctx *gin.Context) {param := ctx.Param("path")ctx.JSON(200, param)
})

处理函数

定义:

type HandlerFunc func(*Context)

通过上下文的参数,获取http的请求参数,响应http请求等。

分组路由

在进行开发的时候,我们往往要进行模块的划分,比如用户模块,以user开发,商品模块,以goods开头。

或者进行多版本开发,不同版本之间路径是一致的,这种时候,就可以用到分组路由了。

比如

ug := r.Group("/user")
{ug.GET("find", func(ctx *gin.Context) {ctx.JSON(200, "user find")})ug.POST("save", func(ctx *gin.Context) {ctx.JSON(200, "user save")})
}
gg := r.Group("/goods")
{gg.GET("find", func(ctx *gin.Context) {ctx.JSON(200, "goods find")})gg.POST("save", func(ctx *gin.Context) {ctx.JSON(200, "goods save")})
}

请求路径则为

[GIN-debug] GET    /user/find                --> main.main.func2 (3 handlers)
[GIN-debug] POST   /user/save                --> main.main.func3 (3 handlers)
[GIN-debug] GET    /goods/find               --> main.main.func4 (3 handlers)
[GIN-debug] POST   /goods/save               --> main.main.func5 (3 handlers)

请求参数

GET请求参数

使用Get请求传参时,类似于这样

http://localhost:8080/user/save?id=11&name=zhangsan

如何获取呢?

普通参数

request url: http://localhost:8080/user/save?id=11&name=zhangsan

  • Query:匹配字段

    r.GET("/user/save", func(ctx *gin.Context) {id := ctx.Query("id")name := ctx.Query("name")ctx.JSON(200, gin.H{"id":   id,"name": name,})
    })
    

    如果参数不存在,就给一个默认值:

  • DefaultQuery:query为空时回返回个默认值

    r.GET("/user/save", func(ctx *gin.Context) {id := ctx.Query("id")name := ctx.Query("name")address := ctx.DefaultQuery("address", "北京")ctx.JSON(200, gin.H{"id":      id,"name":    name,"address": address,})
    })
    
  • GetQuery:多了个query成功与否的返回值

    r.GET("/user/save", func(ctx *gin.Context) {id, ok := ctx.GetQuery("id")address, aok := ctx.GetQuery("address")ctx.JSON(200, gin.H{"id":      id,"idok":    ok,"address": address,"aok":     aok,})
    })
    

    id是数值类型,上述获取的都是string类型,根据类型获取:通过form进行字段匹配

  • BindQuery:与结构体字段进行匹配

    type User struct {Id   int64  `form:"id"`Name string `form:"name"`
    }
    r.GET("/user/save", func(ctx *gin.Context) {var user Usererr := ctx.BindQuery(&user)if err != nil {log.Println(err)}ctx.JSON(200, user)
    })
    
  • ShouldBindQuery:有binding字段的要求必填,否则报错

    r.GET("/user/save", func(ctx *gin.Context) {var user Usererr := ctx.ShouldBindQuery(&user)if err != nil {log.Println(err)}ctx.JSON(200, user)
    })
    

    区别

    当bind是必须的时候,ShouldBindQuery会报错,开发者自行处理,状态码不变。

    type User struct {Id      int64  `form:"id"`Name    string `form:"name"`Address string `form:"address" binding:"required"`
    }
    

    BindQuery则报错的同时,会将状态码改为400。所以一般建议是使用Should开头的bind。

数组参数

请求url:http://localhost:8080/user/save?address=Beijing&address=shanghai

  • QueryArray:重复查询字段组装成数组

    r.GET("/user/save", func(ctx *gin.Context) {address := ctx.QueryArray("address")ctx.JSON(200, address)
    })
    
  • GetQueryArray:多成功与否返回值

    r.GET("/user/save", func(ctx *gin.Context) {address, ok := ctx.GetQueryArray("address")fmt.Println(ok)ctx.JSON(200, address)
    })
    
  • ShouldBindQuery

    r.GET("/user/save", func(ctx *gin.Context) {var user Usererr := ctx.ShouldBindQuery(&user)fmt.Println(err)ctx.JSON(200, user)
    })
    

    但是这样的话我们的user的address要求就是个数组

    type User struct {Id      int64    `form:"id"`Name    string   `form:"name"`Address []string `form:"address" binding:"required"`
    }
    

    成功返回

    {"Id": 0,"Name": "","Address": ["Beijing","shanghai"]
    }
    

map参数

请求url:http://localhost:8080/user/save?addressMap[home]=Beijing&addressMap[company]=shanghai

  • QueryMap:组装成map

    r.GET("/user/save", func(ctx *gin.Context) {addressMap := ctx.QueryMap("addressMap")ctx.JSON(200, addressMap)
    })
    
  • GetQueryMap:多成功与否返回值

    r.GET("/user/save", func(ctx *gin.Context) {addressMap, _ := ctx.GetQueryMap("addressMap")ctx.JSON(200, addressMap)
    })
    

    返回值

    {"company": "shanghai","home": "Beijing"
    }
    

POST请求参数

post请求一般是表单参数和json参数

表单参数

r.POST("/user/save", func(ctx *gin.Context) {id := ctx.PostForm("id")name := ctx.PostForm("name")address := ctx.PostFormArray("address")addressMap := ctx.PostFormMap("addressMap")ctx.JSON(200, gin.H{"id":         id,"name":       name,"address":    address,"addressMap": addressMap,})
})
  • PostForm:从表单中对应的字段
  • PostFormArray:从表单找对应的数组
  • PostFormMap:从表单找对应的Map
r.POST("/user/save", func(ctx *gin.Context) {var user Usererr := ctx.ShouldBind(&user)addressMap, _ := ctx.GetPostFormMap("addressMap")user.AddressMap = addressMapfmt.Println(err)ctx.JSON(200, user)
})
  • GetPostFormMap:从表单找对应的Map

JSON参数

json参数如下

{"id":1111,"name":"zhangsan","address": ["beijing","shanghai"],"addressMap":{"home":"beijing"}
}
r.POST("/user/save", func(ctx *gin.Context) {var user Usererr := ctx.ShouldBindJSON(&user)fmt.Println(err)ctx.JSON(200, user)
})

对应字段进行匹配

其他类型参数注入xml,yaml等和json道理一样

路径参数

请求url:http://localhost:8080/user/save/111

r.POST("/user/save/:id", func(ctx *gin.Context) {ctx.JSON(200, ctx.Param("id"))
})
  • :id 表示 占位符,可以匹配 任意路径中的值

  • ctx.Param("id") 用于 获取路径参数 id 的值

文件参数

r.POST("/user/save", func(ctx *gin.Context) {form, err := ctx.MultipartForm()if err != nil {log.Println(err)}files := form.Filefor _, fileArray := range files {for _, v := range fileArray {ctx.SaveUploadedFile(v, "./"+v.Filename)}}ctx.JSON(200, form.Value)
})

在form表单中请求file类型

在这里插入图片描述

这样就能在本地看到了

在这里插入图片描述

响应

字符串方式

r.GET("/user/save", func(ctx *gin.Context) {ctx.String(http.StatusOK, "this is a %s", "ms string response")
})

JSON方式

r.GET("/user/save", func(ctx *gin.Context) {ctx.JSON(http.StatusOK, gin.H{"success": true,})
})

XML方式

r.GET("/user/save", func(ctx *gin.Context) {u := XmlUser{Id:   11,Name: "zhangsan",}ctx.XML(http.StatusOK, u)
})

文件方式

r.GET("/user/save", func(ctx *gin.Context) {//ctx.File("./1.png")ctx.FileAttachment("./1.png", "2.png")
})

设置http响应头

r.GET("/user/save", func(ctx *gin.Context) {ctx.Header("test", "headertest")
})

重定向

r.GET("/user/save", func(ctx *gin.Context) {ctx.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
})

YAML方式

r.GET("/user/save", func(ctx *gin.Context) {ctx.YAML(200, gin.H{"name": "ms", "age": 19})
})

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

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

相关文章

哈尔滨算力服务器托管推荐-青蛙云

哈尔滨年平均气温3.5摄氏度,有发展云计算和算力数据中心的天然优势 ,今天为哈尔滨算力服务器托管服务商:青蛙云,黑龙江经营17年的老牌IDC服务商。 先来了解下算力服务器: 算力服务器,尤其是那些用于运行人…

【C++】每日一练(有效的括号)

本篇博客给大家带来的是用C语言来解答有效的括号! 🐟🐟文章专栏:每日一练 🚀🚀若有问题评论区下讨论,我会及时回答 ❤❤欢迎大家点赞、收藏、分享! 今日思想:不服输的少年…

51单片机的keil c51软件安装教程

Keil(C51)介绍、下载、安装与注册_keil c51-CSDN博客 参考 安装 不一定是这个大小,也可以下载别的版本KEID C51 注册 加入芯片型号 …

DeepIn Wps 字体缺失问题

系统缺失字体 Symbol 、Wingdings 、Wingdings2、Wingdings3、MT—extra 字体问题 问了下DeepSeek 在应用商店安装或者在windows 里面找 装了一个GB-18030 还是不行 在windows里面复制了缺失的字体 将字体复制到DeepIn 的字体目录(Ubuntu 应该也是这个目录&am…

【性能测试】Jmeter详细操作-小白使用手册(2)

本篇文章主要介绍Jmeter中如何使用 JSON断言、同步定时器、事务控制器、CSV数据文件设置、HTTP Cookie管理器 目录 一:JSON断言 1:正确结果展示 2:错误结果展示 3:JSON配置 (1)Additionally assert …

分布式锁—Redisson的同步器组件

1.Redisson的分布式锁简单总结 Redisson分布式锁包括:可重入锁、公平锁、联锁、红锁、读写锁。 (1)可重入锁RedissonLock 非公平锁,最基础的分布式锁,最常用的锁。 (2)公平锁RedissonFairLock 各个客户端尝试获取锁时会排队,按照队…

国产编辑器EverEdit - 脚本(解锁文本编辑的无限可能)

1 脚本 1.1 应用场景 脚本是一种功能扩展代码,用于提供一些编辑器通用功能提供不了的功能,帮助用户在特定工作场景下提高工作效率,几乎所有主流的编辑器、IDE都支持脚本。   EverEdit的脚本支持js(语法与javascript类似)、VBScript两种编程…

[leetcode]位运算

一.AND &运算 注:两个操作数做&运算结果是不会变大的 二.OR |运算 注:两个操作数做|运算结果是不会变小的 三.XOR(异或) ^运算 注:结果可能变大也可能变小也可能不变,但是不会导致进位,比如两个四位的数字做…

Python爬虫---中国大学MOOC爬取数据(文中有数据集)

1、内容简介 本文为大二在校学生所做,内容为爬取中国大学Mooc网站的课程分类数据、课程数据、评论数据。数据集大佬们需要拿走。主要是希望大佬们能指正代码问题。 2、数据集 课程评论数据集,343525条(包括评论id、评论时间、发送评论用户…

Tomcat 安装

一、Tomcat 下载 官网:Apache Tomcat - Welcome! 1.1.下载安装包 下载安装包: wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.102/bin/apache-tomcat-9.0.102.tar.gz 安装 javajdk。 yum install java-1.8.0-openjdk.x86_64 -y /etc/altern…

MC34063数据手册解读:功能、应用与设计指南

MC34063A/MC33063A 系列是摩托罗拉(现 NXP)推出的高集成度 DC-DC 转换器控制电路,适用于降压、升压和反相应用。本文将基于官方数据手册,对其核心功能、关键参数、典型应用及设计要点进行详细解读。 一、核心功能与特性 集成度高…

基于SpringBoot实现旅游酒店平台功能十一

一、前言介绍: 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高,旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求,旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上&#xff0…

Linux入门 全面整理终端 Bash、Vim 基础命令速记

Linux入门 2025 超详细全面整理 Bash、Vim 基础命令速记 刚面对高级感满满的 终端窗口是不是有点懵?于是乎,这份手册就是为你准备的高效学习指南!我把那些让人头大的系统设置、记不住的命令都整理成了对你更友好的格式,让你快速学…

基于deepseek的图像生成系统

目录 问题 核心思路 pollinations 提示词 基于deepseek的图像生成系统 项目说明 详细说明 1. 注册流程 2. 登录流程 3. 图片生成流程 4. 图片下载流程 项目结构 代码实现 1. 配置文件 config.py 2. 数据库模型 models.py 3. 解决循环引用 exts.py 4. 登录和…

mac安装mysql之后报错zsh: command not found: mysql !

在Mac上安装MySQL后,如果终端中找不到mysql命令,通常是 因为MySQL的命令行工具(如mysql客户端)没有被正确地添加到你的环境变量中。 检查 MySQL 是否已安装 ps -ef|grep mysql查看到路径在 /usr/local/mysql/bin 查看 .bash_pro…

Mybatis3 调用存储过程

1. 数据库MySQL,user表 CREATE TABLE user (USER_ID int NOT NULL AUTO_INCREMENT,USER_NAME varchar(100) NOT NULL COMMENT 用户姓名,AGE int NOT NULL COMMENT 年龄,CREATED_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,CREATED_BY varchar(100) NOT NUL…

STM32 HAL库实战:轻松实现串口通信驱动蓝牙模块与ESP8266开发

STM32 HAL库实战:轻松实现串口通信驱动蓝牙模块与ESP8266开发 引言 STM32F103C8T6作为一款性能强劲的32位微控制器,广泛应用于各类嵌入式系统。本文将详细介绍如何使用STM32F103C8T6的HAL库进行串口通信,并展示如何通过串口驱动蓝牙模块&…

Discuz建站教程之论坛头部logo跳转链接怎么修改?

在修改头部logo跳转链接前&#xff0c;我们需要知道对应代码在哪个文件目录&#xff0c;进入宝塔或是服务器&#xff0c;找到文件&#xff1a;\template\default\common\header.htm&#xff0c;编辑器打开&#xff0c;搜索以下代码&#xff0c;大概在135行 <a href"{i…

python-leetcode-最大连续1的个数 III

1004. 最大连续1的个数 III - 力扣&#xff08;LeetCode&#xff09; 使用滑动窗口的方法来解决这个问题。 思路&#xff1a; 使用双指针&#xff08;滑动窗口&#xff09;&#xff0c;定义左右边界 left 和 right。维护窗口内最多包含 k 个 0。当窗口内的 0 超过 k 个时&…

基于Vue3的流程图绘制库

流程图组件的革命者&#xff0c;带你探索无限可能Vue Flow 基于Vue3的流程图绘制库