1. Gin
1.1 下载相应依赖
创建go项目,在项目下建立go.mod文件(若有则跳过)
命令行运行
go get github.com/gin-gonic/gin
1.2 启动一个简单Web服务
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
// 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 如何返回网页
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中的操作
<!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 如何从请求中获取参数
// 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 路由和重定向
// 重定向
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中间件
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)
})
})