安装方式
$ go get -u github.com/gin-gonic/gin
引入gin
import “github.com/gin-gonic/gin”
package main import ( "github.com/gin-gonic/gin" ) func Hello(c *gin.Context) {
c.String(200, "hello,go") } func main() {
e := gin.Default() e.GET("/hello", Hello) e.Run() }
访问页面localhost:8080/hello 就可以看到hello,go
gin默认运行在8080端口,我们可以看出,gin其实是基于httprouter建立的,我们使用httprouter也可以还原上面的逻辑
package main import ( "fmt" "log" "net/http" "github.com/julienschmidt/httprouter" ) func Hello(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
fmt.Fprintf(w, "hello,go") } func main() {
router := httprouter.New() router.GET("/hello", Hello) log.Fatal(http.ListenAndServe(":8080", router)) }
但是我们明显可以发现,使用gin会优雅很多
在gin中我们约定,将所有需要使用到的html文件都放到templates文件夹下
登陆页面 login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div> //方法名为post 因为我们需要用post方法调用提交功能,action为我们提交后需要跳转的位置 <form action="/welcome" method="post"> userName: <input type="text" class="text" name="userName"><br> passWord: <input type="password" name="password"><br> <input type="submit" value="提交"> </form> </div> </body> </html>
登录成功后进入的界面 welcome.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <p> welcome {
{.userName}} </p> </body> </html>
main.go
package main import ( "net/http" "github.com/gin-gonic/gin" ) func Login(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", nil) } func DoWelcom(c *gin.Context) {
//*gin.Context是gin中一个非常关键的上下文流 // 为了拿到form内名为username输入框的内容 userName := c.PostForm("userName") c.HTML(http.StatusOK, "welcome.html", gin.H{
//给welcone.html文件传递username "userName": userName, }) } func main() {
e := gin.Default() //获取html文件流 e.LoadHTMLGlob("templates/*") e.GET("/login", Login) e.POST("/welcome", DoWelcom) e.Run() }
GET其实就是进行穿参的一种方法,跟在路由后的params,下面的方法就类似于在路由路径后加上 ?username=“”&password=“” 123和111分别是默认数据
func testGet(c *gin.Context) {
s := c.DefaultQuery("username", "123") password := c.DefaultQuery("password", "111") c.String(200, "username:%s,password:%s", s, password) }
通过定义一个结构体来绑定表单内的参数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div> <form action="/regiester" method="post"> userName: <input type="text" class="text" name="userName"><br> passWord: <input type="password" name="password"><br> 爱好: <input type="checkbox" name="hobby" value="swmming" id="">游泳 <input type="checkbox" name="hobby" value="run" id="">跑步 <br> 性别: <input type="radio" name="gender" value="1" id="">男 <input type="radio" name="gender" value="2" id="">女 城市 <select name="city" id=""> <option value="beijing">北京</option> <option value="shenzhen">深圳</option> </select> <input type="submit" value="提交"> </form> </div> </body> </html>
package main import ( "net/http" "github.com/gin-gonic/gin" ) type User struct {
UserName string `form:"userName"` Password string `form:"password"` Hobby []string `form:"hobby"` Gender string `form:"gender"` City string `form:"city"` } func Regiester(c *gin.Context) {
var user User c.ShouldBind(&user) c.String(200, "USER:%s", user) } func main() {
e := gin.Default() e.LoadHTMLGlob("templates/*") e.GET("/login", Login) e.POST("/regiester", Regiester) e.Run() }
bootstrapExp.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="../assets/css/bootstrap.min.css"> <script src="../assets/js/bootstrap.min.js"></script> </head> <body> <label for="customRange1" class="form-label">Example range</label> <input type="range" class="form-range" id="customRange1"> </body> </html>
main.go
package main import "github.com/gin-gonic/gin" func assents(c *gin.Context) {
c.HTML(200, "bootstrapExp.html", nil) } func main() {
e := gin.Default() e.LoadHTMLGlob("templates/*") e.GET("/assents", assents) e.Run() }
打开localhost:8080/assents就可以看到我们引入的bootstrap进度条组件
中间件就是在运行之后,构造之前中间这一段时间发生的方法,可以用来做数据处理,拦截等用途
当我们默认实例化gin时,使用到的gin.Default()方法,其实已经帮我们默认加载了两个中间件,我们看Default方法是怎么构成的
func Default() *Engine {
debugPrintWARNINGDefault() engine := New() engine.Use(Logger(), Recovery()) return engine }
Default方法创建gin实例时,默认加入logger和recovert中间件
当我们不想使用这两个中间件时,可以这样初始化gin
e:= gin.New()
此时的e是没有任何中间件的
中间件其实就是一个方法,创建中间件就是创建一个方法,我们使用
Use()方法,把中间件方法作为参数传给Use()就是挂载了中间件
package main import ( "fmt" "github.com/gin-gonic/gin" ) func testMiddleWare(c *gin.Context) {
c.String(200, "hello,%s", "lyi") } func middleware1(c *gin.Context) {
fmt.Printf("你好我是中间件1") } func midellware2(c *gin.Context) {
fmt.Printf("你好我是中间件2") } func main() {
e := gin.Default() e.Use(middleware1) e.GET("/middleware", testMiddleWare) e.Use(midellware2) e.Run() }
我们可以看到middleware1和middleware2是在挂载前和挂载后的,在运行的时候,我们也就只能看到挂载前的中间件,也就是middleware1的运行结果
[GIN-debug] GET /middleware --> main.testMiddleWare (4 handlers) [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080 你好我是中间件1[GIN] 2022/06/23 - 14:59:05 | 200 | 66.292µs | ::1 | GET "/middleware"
// 模拟一些私人数据 var secrets = gin.H{
"foo": gin.H{
"email": "foo@bar.com", "phone": ""}, "austin": gin.H{
"email": "austin@example.com", "phone": "666"}, "lena": gin.H{
"email": "lena@guapa.com", "phone": ""}, } func main() {
r := gin.Default() // 路由组使用 gin.BasicAuth() 中间件 // gin.Accounts 是 map[string]string 的一种快捷方式 authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
"foo": "bar", "austin": "1234", "lena": "hello2", "manu": "4321", })) // /admin/secrets 端点 // 触发 "localhost:8080/admin/secrets authorized.GET("/secrets", func(c *gin.Context) {
// 获取用户,它是由 BasicAuth 中间件设置的 user := c.MustGet(gin.AuthUserKey).(string) if secret, ok := secrets[user]; ok {
c.JSON(http.StatusOK, gin.H{
"user": user, "secret": secret}) } else {
c.JSON(http.StatusOK, gin.H{
"user": user, "secret": "NO SECRET :("}) } }) // 监听并在 0.0.0.0:8080 上启动服务 r.Run(":8080") }
package main import ( "fmt" "github.com/gin-gonic/gin" ) func main() {
e := gin.Default() e.GET("/cookie", func(ctx *gin.Context) {
s, err := ctx.Cookie("go_cookie") if err != nil {
s = "no_cookie" ctx.SetCookie("go_cookie", //cookie名称 s, //cookie实例 10, //cookie保存时间,单位是s "/", //路径 "localhost", //域 false, //安全模式,如果开启,将只能通过https模式访问 true, //httpOnly ) } fmt.Printf("s: %v\n", s) }) e.Run() }
打开浏览器我们就能在控制台中找到cookie数据