golang——Gin框架及路由介绍

一. 框架介绍

        Gin是一个轻量级的Go语言Web框架,它具有高性能和简洁的设计。由于其快速的路由匹配和处理性能,Gin成为Go语言中最受欢迎的Web框架之一。

        特点:

  • 快速和轻量:Gin框架的设计注重性能和效率,采用了一些优化措施,使其成为一个快速而轻量级的框架。
  • 路由和中间件:Gin提供了强大的路由功能,支持参数传递,路由分组等特性。同时,它支持中间件的使用,可以方便的在请求处理过程中执行一系列的操作,比如身份验证,日志记录等。
  • json解析:Gin内置了对json的解析和序列化支持,使得处理json数据变得简单而高效。
  • 支持插件:Gin允许开发者通过插件来扩展框架的功能,这样可以根据项目的需求进行灵活定制。

文档:

  • Github地址:https://github.com/gin-gonic/gin
  • 中文文档:https://gin-gonic.com/zh-cn/docs/

 二. 安装

        要安装Gin软件包,您需要安装Go并首先设置Go工作区。

  • 命令安装Gin
go get github.com/gin-gonic/gin@latest
  • 导入代码
import "github.com/gin-gonic/gin"

 三. 第一个Gin应用

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {//将应用切换到“发布模式”以提升性能gin.SetMode(gin.ReleaseMode)//创建路由r := gin.Default()//绑定路由规则,执行函数//gin.Context,封装了request和responser.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "hello world")})//监听端口,默认绑定端口8080r.Run(":8080")
}

代码解释:

  • gin.Default:创建一个Gin引擎。gin.Default()返回一个带有默认中间件的Gin引擎,包括Logger和Recovery中间件,用于日志记录和恢复。
  •  r.Get("/", func(c *gin.Context){...}):定义了一个GET方法的路由,当访问路径是"/"时,执行后面的回调函数。
  • c.String(http.StatusOK, "hello world"):在回调函数中,通过c.String方法返回一个字符串"hello world"并设置HTTP状态码为200 OK。
  • s.Run(":8080"):启动Web服务,监听在0.0.0.0:8080。如果不指定端口号,默认使用8080端口。此时,你可以通过浏览器或HTTP客户端访问http://localhost:8080,将会得到"hello world"的响应。

四. 应用举例

        以下项目都是使用Gin框架开发的:

  • gorush:Go 编写的通知推送服务器。
  • fnproject:容器原生,云 serverless 平台。
  • photoprism:基于 Go 和 Google TensorFlow 实现的个人照片管理工具。
  • krakend:拥有中间件的超高性能 API 网关。
  • picfit:Go 编写的图像尺寸调整服务器。
  • gotify:基于 WebSocket 进行实时消息收发的简单服务器。
  • cds:企业级持续交付和 DevOps 自动化开源平台。

五. Gin入门

  • gin.Engine

        在Gin里面,一个Web服务器被抽象成了Engnie。你可以在一个应用里面创建多个Engine实例,监听不同的端口。Engine承担了路由注册,接入中间件的核心职责。

        它组合了RouterGroup,RouterGroup才是实现路由功能的核心组件。

  • gin.Context

        gin.Context是Gin里面的核心类型。字面意思是"上下文",在Gin里面的核心职责是:

  • 处理请求
  • 返回响应 

六. 路由

        6.1 介绍

  • gin框架中采用的路由库是基于httprouter做的
  • 地址为:https://github.com/julienschmidt/httprouter
  •  支持Restful风格的API,意思是"表面层状态转化",是一个互联网应用程序的API设计理念:URL定位资源。
  • 可以创建路由组,为了管理相同的URL。
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {//将应用切换到“发布模式”以提升性能gin.SetMode(gin.ReleaseMode)//创建路由//默认使用了两个中间件Logger(),Recovery()r := gin.Default()r.GET("/hello1", func(c *gin.Context) {c.String(http.StatusOK, "hello1")})r.GET("/hello2", func(c *gin.Context) {c.String(http.StatusOK, "hello2")})//路由组1v1 := r.Group("/v1"){v1.GET("/hellov1", func(c *gin.Context) {c.String(http.StatusOK, "hello v1")})v1.GET("hellov11", func(c *gin.Context) {c.String(http.StatusOK, "hello v11")})}//路由组2v2 := r.Group("/v2"){v2.GET("/hellov2", func(c *gin.Context) {c.String(http.StatusOK, "hello v2")})v2.POST("/hellov22", func(c *gin.Context) {c.String(http.StatusOK, "hello v22")})}//监听端口,默认绑定端口8080r.Run(":8080")
}

        6.2  API参数 

  • 可以通过Context的Param方法来获取API参数
package mainimport ("fmt""net/http""strings""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/user/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")fmt.Println(name, ":", action) //对于url /user/wy/aa 打印 wy : /aa//去除/action = strings.Trim(action, "/")c.String(http.StatusOK, name+" is "+action)})r.Run()
}

        6.3 URL参数

  • URL参数可以通过DefaultQuery()或Query方法获取
  • DefaultQuery()若参数不存在,返回默认值。Query()若参数不存在,返回空串。
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.GET("/user", func(c *gin.Context) {name := c.Query("name")action := c.DefaultQuery("action", "")c.String(http.StatusOK, name+" is "+action)})r.Run()
}

        6.4 表单参数

  • 表单传输参数为POST请求,http常见的传输格式为四种:

    • application/json

    • application/x-www-form-urlencode

    • application/xml

    • mulipart/form-data

  • 表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencode或form-data格式的参数。

POST请求的html代码:

<!--test.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="/form" method="post"
action="application/x-www-form-urlencoded">
用户名:<input type="text" name="username" placeholder="请输入你的用户名">
<br>密&nbsp;&nbsp;&nbsp;码:<input type="password" name="userpassword"
placeholder="请输入你的密码"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>

服务端代码

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()//设置HTML文件所在目录r.LoadHTMLGlob("./*.html")//设置GET方法路由,成功返回test.html文件r.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "test.html", nil)})//设置POST方法路由r.POST("/form", func(c *gin.Context) {//设置没有传的参数的默认值types := c.DefaultPostForm("type", "post")username := c.PostForm("username")password := c.PostForm("userpassword")c.String(http.StatusOK, "username:%s, userpassword:%s, types:%s", username, password, types)})r.Run()
}

演示:

         6.5 上传文件

上传单个文件:

  • multipart/form-data格式用于上传文件
  • gin文件上传与原生的net/http方法类似,不同在于gin吧原生的request封装到了c.Request中。
package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()//设置HTML文件所在目录r.LoadHTMLGlob("./*.html")//设置GET方法路由,成功返回test.html文件r.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "test.html", nil)})//设置POST方法路由r.MaxMultipartMemory = 8 << 20 //限制上传最大尺寸r.POST("/upload", func(c *gin.Context) {//用于获取表单信息中file格式的参数,并且返回一个文件流file, err := c.FormFile("file") //html中的nameif err != nil {c.String(500, "上次图片错误")}//参数1为指定需要保存操作的文件,参数2为指定保存路径。c.SaveUploadedFile(file, file.Filename)//返回文件名c.String(http.StatusOK, file.Filename)})r.Run()
}

 演示:

上传特定文件:

        有的用户上传文件需要限制文件的类型以及上传文件的大小,可以基于原生的函数写法自己写一个可以限制大小以及文件类型的上传函数。

package mainimport ("net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.LoadHTMLGlob("./*.html")r.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "test.html", nil)})r.POST("/upload", func(c *gin.Context) {_, header, err := c.Request.FormFile("file")if err != nil {c.String(405, "文件错误")return}if header.Size > 1024*1024*2 {c.String(406, "文件太大")return}if header.Header.Get("Content-Type") != "image/png" {c.String(407, "只允许上传图片")return}c.SaveUploadedFile(header, header.Filename)c.String(http.StatusOK, header.Filename)})r.Run()
}

上传多个文件:

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)func main() {r := gin.Default()r.LoadHTMLGlob("./*.html")r.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "test.html", nil)})//限制表单上传大小8MB 默认32MBr.MaxMultipartMemory = 8 << 20 * 2r.POST("/upload", func(c *gin.Context) {//用于获取multipart表单。当用户通过表单上传文件时,浏览器通常会将表单编码为multipart/form-data格式。form, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get a %v", err))return}//获取所有文件files := form.File["files"]//遍历所有文件for _, file := range files {if err := c.SaveUploadedFile(file, file.Filename); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload get a %v", err))return}}c.String(http.StatusOK, fmt.Sprintf("upload %d files ok", len(files)))})r.Run()
}

         6.6 路由原理

        httprouter会将所有路由规则构造一棵前缀树。

        例如有root,and,as,at,cn,com

        6.7 路由拆分与注册

  • 基本的路由注册

         下面最基础的gin路由注册方式,使用于路由条目比较少的简单项目或者项目demo。

package mainimport ("fmt""net/http""github.com/gin-gonic/gin"
)func sayHello(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "hello go",})
}func main() {r := gin.Default()r.GET("/hello", sayHello)if err := r.Run(); err != nil {fmt.Printf("startup server err : %v", err)}
}
  • 路由拆分成单独文件或包 

        当项目的规模增大后,就不适合继续在项目的main.go文件中实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包。

  • 形成单独文件

  • 形成独立的包 

  • 拆分成多个文件

        当业务规模继续膨胀,单独的一个router文件或包已经满足不了我们的需求了。 因为我们把所有的路由注册都写在一个SetRouter函数中的话会很复杂。

        我们可以将其拆分为多个文件。

  • 路由拆分到不同APP 

        有时候项目规模太大,那么我们就更倾向于把业务拆分的更加详细,例如把不同的业务代码拆分成不同的APP。

        因此我们在项目目录下单独定义一个app目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。

目录结构:

app/blog:

代码如下: 

gin/app/shop: 

 gin/router/router.go

 gin/main.go

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

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

相关文章

第二十一章 网络编程

​ 一、网络的相关概念 1. 网络通信 &#xff08;1&#xff09;网络通信&#xff1a;将 数据 通过网络从一台设备传输到另一台设备 &#xff08;2&#xff09;java.net 包下提供了一系列的类或接口&#xff0c;完成网络通信 2. 网络 概念&#xff1a;两台或多台设备通过一定…

轻松省电!教你苹果手机自动调节亮度怎么设置

在日常使用手机的过程中&#xff0c;屏幕亮度是影响电池续航的关键因素之一。苹果手机提供的自动调节亮度功能&#xff0c;可以根据环境光线自动调整屏幕亮度&#xff0c;从而提供最佳的视觉体验并有效延长电池使用时间。想知道苹果手机自动调节亮度怎么设置吗&#xff1f; 本…

工厂自动化相关设备工业一体机起到什么作用?

在当今的制造业领域&#xff0c;工厂自动化已成为提高生产效率、保证产品质量和降低成本的关键。在这一进程中&#xff0c;工业一体机作为一种重要的设备&#xff0c;发挥着不可或缺的作用。 工业一体机是自动化生产线上的控制中心。它能够整合和处理来自各个传感器、执行器和其…

02:vim的使用和权限管控

vim的使用 1、vim基础使用1.1、vim pathname 2、vim高级用法2.1、查找2.2、设置显示行号2.3、快速切换行2.4、 行删除2.5、行复制粘贴 3、权限管理3.1、普通用户和特权用户3.2、文件权限表示 vim是Linux中的一种编辑器&#xff0c;类似于window中的记事本&#xff0c;可以对创建…

产业链协同,共谋产业新高度

国际数字影像产业园始终秉承“产业协同&#xff0c;共谋发展”的核心理念&#xff0c;致力于通过深化产业链上下游的紧密合作&#xff0c;推动数字影像产业的持续繁荣。 一、产业协同的具体实践 1、产业链整合&#xff1a;园区积极整合数字影像产业的上下游资源&#xff0c;形…

Prometheus 监控服务器

Prometheus概述 组件化设置&#xff1a;nginx ,ceph , Prometheus 部署Prometheus服务器 配置时间 安装Prometheus服务器 访问web页面&#xff1a;http://192.168.88.5:9090/ 添加被监控端 监控方式&#xff1a; 拉取&#xff1a;pull。监控端联系被监控端&#xff0c;采集数…

Apache APISIX遇到504超时的解决办法

说明&#xff1a; Apache APISIX版本&#xff1a;v3.9.0Apache APISIX Dashboard版本&#xff1a;v3.0.1 当使用Apache APISIX开源网关&#xff0c;通过接口上传或下载大文件等时&#xff0c;出现如下“504 Gateway Time-out”错误信息&#xff0c;它表示网关或代理服务器未能…

springboot系列六: springboot底层机制实现 下

实现SpringBoot底层机制[Tomcat启动分析 Spring容器初始化 Tomcat如何关联Spring容器] 实现任务阶段1-创建Tomcat, 并启动&#x1f966;说明&#xff1a;创建Tomcat, 并启动&#x1f966;分析代码实现&#x1f966;完成测试 实现任务阶段2-创建Spring容器&#x1f966;说明&a…

H5项目使用vant组件的手机号校验

前言&#xff1a; 在开发h5项目的时候遇到手机号校验&#xff0c;原本想采用后台管理那种校验方式&#xff08;validator函数写校验手机号逻辑&#xff09;猛然间发现&#xff0c;可以在使用行内使用pattern属性 用法如下 <van-form submit"onSubmit"><van-…

bug,属性注入时为null

因为在使用拦截器时使用的是new的这个类放容器的 解决方法&#xff1a; 使用有参构造器&#xff0c;在new对象时传入值

鸿蒙开发设备管理:【@ohos.sensor (传感器)】

传感器 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import sensor from ohos.sensor;sensor.on ACCELEROMETER on(type: SensorType.SENSOR_TYPE_ID_ACCELEROMETER, callback: C…

HexPlane: A Fast Representation for Dynamic Scenes(总结图)

图1。用于动态三维场景的 Hex刨面。我们没有从深度 MLP 中回归颜色和不透明度&#xff0c;而是通过 HexPlann 显式地计算时空点的特征。配对一个微小的 MLP&#xff0c;它允许以上100倍加速匹配的质量。 图2。方法概述。Hex刨包含六个特征平面&#xff0c;跨越每对坐标轴(例如…

PyTorch计算机视觉实战:目标检测、图像处理与深度学习

本书基于真实数据集&#xff0c;全面系统地阐述现代计算机视觉实用技术、方法和实践&#xff0c;涵盖50多个计算机视觉问题。全书分为四部分&#xff1a;一部分介绍神经网络和PyTorch的基础知识&#xff0c;以及如何使用PyTorch构建并训练神经网络&#xff0c;包括输入数据缩放…

【前端VUE】VUE3第一节—vite创建vue3工程

什么是VUE Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0…

深入了解自动化:聊聊什么项目适合做自动化测试?

自动化测试 什么是自动化测 什么是自动化测试&#xff1f; 随着软件产业的不断发展&#xff0c;市场对软件周期的要求越来越高&#xff0c;于是催生了各种开发模式&#xff0c;如大家熟知的敏捷开发&#xff0c;从而对测试提出了更高的要求。此时&#xff0c;产生了自动化测试…

Linux高并发服务器开发(十)反应堆模型和线程池模型

文章目录 1 epoll反应堆2 线程池流程代码 3 复杂版本线程池代码 1 epoll反应堆 文件描述符 监听事件 回调函数 进行封装 创建socket设置端口复用绑定监听创建epoll树将监听文件描述符lfd上epoll树&#xff0c;对应的事件节点包括&#xff1a;文件描述符&#xff0c;事件epoll…

Taogogo Taocms v3.0.2 远程代码执行漏洞(CVE-2022-25578)

前言 CVE-2022-25578 是一个存在于 Taogogo Taocms v3.0.2 中的代码注入漏洞。此漏洞允许攻击者通过任意编辑 .htaccess 文件来执行代码注入。 漏洞详情 漏洞描述&#xff1a;攻击者可以利用此漏洞上传一个 .htaccess 文件到网站&#xff0c;并在文件中注入恶意代码&#xf…

苹果手机怎么刷机?适合小白的刷机办法!

自己的苹果手机用时间长了&#xff0c;有些人想要为自己的手机重新刷新一下&#xff0c;但又不知道怎么刷机。不要慌现在就来给大家详细介绍一下苹果手机怎么刷机&#xff0c;希望可以帮助到大家。 iPhone常见的刷机方式&#xff0c;分为iTunes官方和第三方软件两种刷机方式。 …

【elementui】记录解决el-tree开启show-checkbox后,勾选一个叶结点后会自动折叠的现象

第一种解决方案&#xff1a;设置default-expand-keys的值为当前选中的key值即可 <el-treeref"tree"class"checkboxSelect-wrap":data"treeData"show-checkboxnode-key"id":expand-on-click-node"true":props"defau…

第T3周:天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、前期工作 本文将采用CNN实现多云、下雨、晴、日出四种天气状态的识别。较上篇文章&#xff0c;本文为了增加模型的泛化能力&#xff0c;新增了Dropout层并…