【GoWeb框架初探————Gin篇】

1. Gin

1.1 下载相应依赖

创建go项目,在项目下建立go.mod文件(若有则跳过)

命令行运行

bash 复制代码
go get github.com/gin-gonic/gin

1.2 启动一个简单Web服务

go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"github.com/thinkerou/favicon"
	"net/http"
)

func main() {
	// 获取一个gin默认的服务器
	ginServer := gin.Default()
	// 修改网站在浏览器的icon
	ginServer.Use(favicon.New("./icon/img.png"))
	// 访问地址,处理我们的请求		Request   Response
	ginServer.GET("/hello", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"msg": "hello,world"})
	})
	// 返回界面
	// 服务端口
	ginServer.Run(":8083")
}

1.3 Gin中的Restful风格API

go 复制代码
	// Gin RestFul风格
	ginServer.GET("/user", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"msg": "GET,user"})
	})
	ginServer.POST("/user", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"msg": "POST,user"})
	})
	ginServer.PUT("/user", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"msg": "PUT,user"})
	})
	ginServer.DELETE("/user", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{"msg": "DELETE,user"})
	})

1.4 如何返回网页

go 复制代码
func main() {
	// 创建一个服务
	ginServer := gin.Default()
	// 修改网站在浏览器的icon
	ginServer.Use(favicon.New("./icon/img.png"))
	// 加载静态页面
	ginServer.LoadHTMLGlob("templates/*")
	// 加载资源文件
	ginServer.Static("/static", "./static")
	// 响应一个页面给前端
	ginServer.GET("index", func(context *gin.Context) {
		context.HTML(http.StatusOK, "index.html", gin.H{"msg": "这是后台来的数据"})
	})
	// 服务端口
	ginServer.Run(":8083")
}

前端html界面使用参数的方法类似于vue中的操作

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我的一个Go Web界面</title>
    <link rel="stylesheet" href="/static/css/style.css">
    <script src="/static/js/common.js"></script>
</head>
<body>
太强啦!
获取后端数据为:{{.msg}}
</body>
</html>

1.5 如何从请求中获取参数

go 复制代码
	// url?userid=xxx&username=kuangshen
	ginServer.GET("/user/info", func(context *gin.Context) {
		userid := context.Query("userid")
		username := context.Query("username")
		context.JSON(http.StatusOK, gin.H{
			"userid":   userid,
			"username": username,
		})
	})
	// /user/info/1/kuangshen
	ginServer.GET("user/info/:userid/:username", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{
			"userid":   context.Param("userid"),
			"username": context.Param("username"),
		})
	})
	// 前端给后端传递json
	ginServer.POST("/json", func(context *gin.Context) {
		body, _ := context.GetRawData()
		var m map[string]interface{}
		// 序列化包装为json
		_ = json.Unmarshal(body, &m)
		context.JSON(http.StatusOK, m)
	})
	// 处理表单的数据
	ginServer.POST("/user/add", func(context *gin.Context) {
		context.JSON(http.StatusOK, gin.H{
			"userid":   context.PostForm("userid"),
			"username": context.PostForm("username"),
		})
	})

1.6 路由和重定向

go 复制代码
	// 重定向
	ginServer.GET("/test", func(context *gin.Context) {
		// 重定向
		context.Redirect(http.StatusMovedPermanently, "https://baidu.com")
	})
	// 404 NoRoute
	ginServer.NoRoute(func(context *gin.Context) {
		context.HTML(http.StatusNotFound, "404.index", nil)
	})

	// 路由组
	userGroup := ginServer.Group("/user")
	{
		userGroup.GET("/add")
		userGroup.POST("/login")
		userGroup.POST("/logout")
	}
	
	v1api := ginServer.Group("/v1")
	v1api.GET("/jack", func(context *gin.Context) {
		context.String(http.StatusOK, "版本v1的jack")
	})

1.7 中间件/拦截器

预处理、登录授权、验证、分页...耗时统计

我们查看GET等请求的参数时,发现第二个参数是...HandlerFunc,表示这是一个可变长的参数,会依次进过这些处理器进行处理。

go 复制代码
// 自定义Go中间件
func myHandler() gin.HandlerFunc {
	return func(context *gin.Context) {
		// 通过自定义的中间值,设置的值,在后续处理只要调用了这个中间件的都可以拿到这里的参数
		context.Set("usersSession", "userId-1")
		context.Next()  //放行
		context.Abort() //阻止
	}
}

//func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes
//也就是说,我们可以通过这样的方式来让请求依次通过多个handler
ginServer.POST("/user/add",myHandler() ,func(context *gin.Context) {
	context.JSON(http.StatusOK, gin.H{
		"userid":   context.PostForm("userid"),
		"username": context.PostForm("username"),
		"usersSession": context.MustGet("usersSession").(string)
	})
})
相关推荐
小杨互联网10 小时前
Go 现代 CLI 工具离线镜像合集
开发语言·后端·golang·开源·go·命令行
hourinX12 小时前
从直接填格子到筛选图案:头像生成这部分是怎样改过来的—— gdenticon 重构日志(三)
go
我不会起名字32215 小时前
Redis 从 0 到 1(十三):分布式锁被误删、锁不住?Go 无 Lua 实现 3 级防御
redis·go·分布式锁·watch·setnx
hourinX1 天前
从 v1 到 v2,我重新拆了头像生成的整条链路—— gdenticon 重构日志(二)
go
FungLeo2 天前
成为全栈·Go 后端篇·分类树与标签关系:目录变更为何需要协调
golang·go·gorm·数据库事务·分类树·成为全栈
FungLeo2 天前
成为全栈·Go 后端篇·文章查询与展示投影:安全分页、排序和软删除
golang·go·gorm·分页查询·成为全栈·sql安全
KevinAshen672 天前
用 Go 修复旧下载工具:从接口 403 到凭证截断的完整复盘
go·github
FungLeo3 天前
成为全栈·Go 后端篇·跨语言认证兼容:Node 与 Go 如何互认 JWT 和密码
golang·go·jwt·身份认证·成为全栈·bcrypt
FungLeo4 天前
成为全栈·Go 后端篇·重写之前先锁基线:契约、Node 版本与行为清单
golang·node.js·go·openapi·契约测试·成为全栈
小满zs4 天前
Go语言第十七章(反射)
后端·go