gin - skynocover/Wiki-for-GoLang GitHub Wiki
//產生一個引擎 帶有logger及Recovery
router := gin.Default()
//載入html
router.LoadHTMLGlob("views/*")
router.StaticFS("/views", http.Dir("/views/assets"))
// 静态文件服务 可以hot fix不用重啟程式
router.Static("/resource", "resource") //載入整個目錄
router.StaticFile("main.css", "./views/assets/css/main.css") //載入單個文件
//註冊路由
//抓取index的網址並顯示serch.html的靜態網頁
router.GET("/index", func(c *gin.Context) {
//根据完整文件名渲染模板,并传递参数
c.HTML(http.StatusOK, "serch.html", gin.H{
"title": "Main website",
})
})
//執行
router.Run(":8080") //localhost:8080
router.GET("/redirect", func(c *gin.Context) {
//支持内部和外部的重定向
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})
v := router.Group("/test") //可以對入口進行分組,網址變成localhost:8080/test/index.html
{
v.GET("/index.html", handler.IndexHandler) //藉由handler來處理
v.GET("/mypage.html", uploadHandler) //藉由handler來處理
v.GET("/login", func(c *gin.Context) { //不藉由handler處理
c.String(http.StatusOK, "v1 login")
})
}
// handler
func uploadHandler(c *gin.Context) { //建立handler(controller)
c.HTML(http.StatusOK, "mypage.html", gin.H{
"Title": "測試頁面", //在html內要有 <title>{{ .Title }}</title> 才會正確顯示
})
}
//v2 := router.Group("/v2", middleware1) 在group中使用中間件
注册一个路由,使用了 middleware1,middleware2 两个中间件
router.GET("/someGet", middleware1, middleware2, handler2)
func middleware1(c *gin.Context) {
log.Println("exec middleware1")
// 执行该中间件之后的逻辑
c.Next()
}
func middleware2(c *gin.Context) {
log.Println("arrive at middleware2")
// 执行该中间件之前,先跳到流程的下一个方法
c.Next()
// 流程中的其他逻辑已经执行完了才會回來這裡
log.Println("exec middleware2")
//你可以写一些逻辑代码
}
func handler2(c *gin.Context) {
log.Println("exec handler")
}
2019/12/15 11:24:55 exec middleware1
2019/12/15 11:24:55 arrive at middleware2
2019/12/15 11:24:55 exec handler
2019/12/15 11:24:55 exec middleware2
//第1種
router.GET("/user/:name/*action", func(c *gin.Context) { //*會把/也抓出來
name := c.Param("name")
action := c.Param("action")
message := name + " is " + action
c.String(http.StatusOK, message)
})
//第2種
router.GET("/welcome", func(c *gin.Context) { //預設值
firstname := c.DefaultQuery("firstname", "Guest")
lastname := c.Query("lastname")
c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
// http://localhost:8080/welcome?firstname=eircu&lastname=wewe
// Hello eircu wewe
// http://localhost:8080/welcome?firstname/&lastname=wewe
// Hello Guest wewe
// http://localhost:8080/welcome?firstname=&lastname=wewe
// Hello wewe
})
router.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", gin.H{
"title": "Main website",
})
})
html內部需要導引至POST的網址
<form action="http://127.0.0.1:8080/form_post"
router.POST("/form_post", func(c *gin.Context) {
message := c.PostForm("message")
nick := c.DefaultPostForm("nick", "anonymous") //有默認參數
/*
c.JSON(http.StatusOK, gin.H{
"status": gin.H{
"status_code": http.StatusOK,
"status": "ok",
},
"message": message,
"nick": nick,
})
*/
//{"message":"","nick":"skycover","status":{"status":"ok","status_code":200}}
c.JSON(200, gin.H{
"status": "posted",
"message": message,
"nick": nick,
})
//{"message":"newmw","nick":"skycover","status":"posted"}
type1 := c.DefaultPostForm("type", "alert") //可设置默认值
username := c.PostForm("username")
password := c.PostForm("password")
//hobbys := c.PostFormMap("hobby")
//hobbys := c.QueryArray("hobby")
hobbys := c.PostFormArray("hobby")
c.String(http.StatusOK, fmt.Sprintf("type is %s, username is %s, password is %s,hobby is %v", type1, username, password, hobbys))
/*
{"message":"newmwwa","nick":"skycover","status":"posted"}
type is alert, username is ericwu, password is aaaa,hobby is [game money]
*/
})
type Person2 struct {
Name string `form:"name"`
Address string `form:"address"`
Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}
//http://localhost:8080/testing2?name=eric&address=here&birthday=2016-01-01
router.GET("/testing2", func(c *gin.Context) {
var person Person2// 绑定到 person
if c.ShouldBind(&person) == nil { //使用shouldbind 會依序使用JSON或XML,之后才是Form進行匹配
//也可以直接指定c.ShouldBindQuery
log.Println(person.Name)
log.Println(person.Address)
log.Println(person.Birthday)
}
})
只要在數據綁定的結構上加上binding即可 binding:"required" 表必要參數,若無則會返回error
type Login struct {
User string `form:"user" json:"user" binding:"required"`
Password string `form:"password" json:"password" binding:"required"`
}
使用Form驗證
// user=manu&password=123
router.GET("/loginForm", func(c *gin.Context) {
var form Login
// 验证数据并绑定
if err := c.ShouldBind(&form); err == nil {
if form.User == "manu" && form.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})
JSON
router.POST("/loginJSON", func(c *gin.Context) {
var json Login
// 验证数据并绑定
if err := c.ShouldBindJSON(&json); err == nil {
if json.User == "manu" && json.Password == "123" {
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
} else {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
}
} else {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
})