Gin介绍
# 1、Gin简介
Gin是用Golang编写的轻量级http web框架,最擅长的是Api接口高并发,当某个接口的性能遭到较大的挑战时,可以考虑使用Gin重写接口。
Gin官网:http://gin-gonic.com/zh-cn/ (opens new window)
golang之热加载
当对代码进行修改时,程序能够自动重新加载并执行,可以快速进行代码测试,省去了每次手动重新编译的问题。
工具1(推荐使用):https://github.com/gravityblast/fresh (opens new window)
工具2:https://github.com/codegangsta/gin (opens new window)
执行fresh时,建议工程不要启动,fresh会在后台自动帮你启动,否则会导致端口冲突。
一个简单的Gin代码:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
//创建一个Engine
// 创建带默认中间件(日志与恢复)的 Gin 路由器
server := gin.Default()
//路由注册
// 定义简单的 GET 路由
server.GET("/hello", func(c *gin.Context) {//gin.Context:处理请求,返回响应
// 返回 JSON 响应
c.JSON(http.StatusOK, "hello go")
})
// 默认端口 8080 启动服务器
// 监听 0.0.0.0:8080(Windows 下为 localhost:8080)
server.Run(":8080")
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在Gin中,一个web服务器被抽象成为Engine,可以在一个应用中创建多个Engine实例,监听不同的端口;
Engine承担了路由注册、接入middleware的核心职责,RouterGroup时实现路由功能的核心组件。
Gin支持的类型路由:(主要)
静态路由:完全匹配的路由
server.GET("/HELLO",func(context *gin.Context) { context.String(http.StatusOK, "这是一个hello的路由") })1
2
3参数路由:路径中带参数的路由,关键是获得参数。(使用Param方法)
//路径访问示例:localhost:8080/users/demon server.GET("/users/:name",func(context *gin.Context) { name := context.Param("name") context.String(http.StatusOK, "这是你传过来的名字 %s",name) })1
2
3
4
5查询参数:与参数路由不大一样,查询参数是指在url后面附着的参数,要使用Query方法拿到查询参数的值。
//路径访问示例:localhost:8080/order?id=123 server.GET("/order",func(context *gin.Context) { id := context.Query("id") context.String(http.StatusOK, "这是你传过来的id %s",id) })1
2
3
4
5通配符路由:任意匹配的路由,不能注册*单独出现的路由,比如"/users/*","/users/*/a"(*只有在//后才可以生效)。
server.GET("/views/*.html",func(context *gin.Context) { path := context.Param(".html") context.String(http.StatusOK, "匹配上的值是 %s ",path) }) /*以下方法的路由均失效*/ //server.GET("/views/item*.html",func(context *gin.Context) { // path := context.Param(".html") // context.String(http.StatusOK, "匹配上的值是 %s ",path) //}) //server.GET("/views/item*abc.html",func(context *gin.Context) { // path := context.Param(".html") // context.String(http.StatusOK, "匹配上的值是 %s ",path) //})1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 2.Gin的注册路由(集中注册和分散注册)
# 集中注册
好处:打开可以看到全部路由
坏处:路由太多时,找起来费劲
//main函数
func main(){
server := gin.Default()
user := &web.UserHandler{}
server.POST("/users/signup", u.SignUp)
server.POST("/users/login", u.Login)
server.POST("/users/edit", u.Edit)
server.GET("/users/profile", u.Profile)
//你这还有其他路由
server.Run(":8080")
}
//UserHandler 处于 web文件夹下
type UserHandler struct {
}
func (u *UserHandler) SignUp(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Login(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Edit(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Profile(ctx *gin.Context) {
//你的代码
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 分散注册
好处:有条理性,路由被分散到相关文件夹或文件下,明确用途
坏处:不好找路由,更容易导致路由冲突
//main函数
func main(){
server := gin.Default()
user := &web.UserHandler{}
user.RegisterRouters(server)
//你这还有其他路由
server.Run(":8080")
}
//UserHandler 处于 web文件夹下
type UserHandler struct {
}
func (u *UserHandler) RegisterRoutes(server *gin.Engine) {
server.POST("/users/signup", u.SignUp)
server.POST("/users/login", u.Login)
server.POST("/users/edit", u.Edit)
server.GET("/users/profile", u.Profile)
}
func (u *UserHandler) SignUp(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Login(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Edit(ctx *gin.Context) {
//你的代码
}
func (u *UserHandler) Profile(ctx *gin.Context) {
//你的代码
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
简化注册的方法:分组路由
当路由都有同一个前缀时,可以将这个前缀提取出并进行分组。
func (u *UserHandler) RegisterRoutes(server *gin.Engine) {
//分组前
//server.POST("/users/signup", u.SignUp)
//server.POST("/users/login", u.Login)
//server.POST("/users/edit", u.Edit)
//server.GET("/users/profile", u.Profile)
//分组后
ug := server.Group("/users")
ug.POST("/signup", u.SignUp)
ug.POST("/login", u.Login)
ug.POST("edit", u.Edit)
ug.GET("profile", u.Profile)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 3.Gin的跨域问题
跨源资源共享(CORS) 是一种基于 HTTP 头的机制,用于允许浏览器从不同源(域、协议或端口)加载资源。
默认情况下,浏览器会遵循同源策略,限制跨域请求以保护用户数据安全。如果服务器未正确配置 CORS,可能会导致请求被阻止。

解决办法:preflight机制。(即告诉浏览器可以接收到从A过来的请求);发到同一个地址上,使用Options方法,没有请求参数。

