初学Golang的web框架gin的一些练手代码。(发帖当个备忘录了)
package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/gin-gonic/gin"
)
type Login struct {
Name string `form:"name" json:"name" binding:"required"`
Age int `form:"age" json:"age" binding:"required"`
}
func cost() gin.HandlerFunc {
return func(c *gin.Context) {
// 处理请求前的逻辑
start := time.Now()
// 处理请求
c.Next()
// 处理请求后的逻辑
end := time.Now()
cost := end.Sub(start)
log.Println("==============")
log.Println("cost:", cost)
}
}
func main() {
fmt.Println("Hello, World!")
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello World!",
})
})
// 获取querystring参数
// http://localhost:8080/query?name=hao&age=18
r.GET("/query", func(c *gin.Context) {
name := c.Query("name") // 获取querystring参数
age := c.Query("age") // 获取querystring参数
c.JSON(200, gin.H{
"name": name,
"age": age,
})
})
// 获取form参数
// http://localhost:8080/user/search
r.POST("/user/search", func(c *gin.Context) {
// DefaultPostForm取不到值时会返回指定的默认值
//username := c.DefaultPostForm("username", "小王子")
username := c.PostForm("username")
age := c.PostForm("age")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"age": age,
})
})
// 获取URl路径参数
// http://localhost:8080/user/hao/18
r.GET("/user/:name/:age", func(c *gin.Context) {
name := c.Param("name") // 获取URL路径参数
age := c.Param("age") // 获取URL路径参数
c.JSON(200, gin.H{
"name": name,
"age": age,
})
})
// 参数绑定
// http://localhost:8080/login?name=hao&age=18
r.GET("/login", func(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
c.JSON(http.StatusOK, gin.H{
"name": login.Name,
"age": login.Age,
})
})
// http://localhost:8080/login_post 请求体body中携带json数据
r.POST("/login_post", func(c *gin.Context) {
var login Login
if err := c.ShouldBind(&login); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
c.JSON(http.StatusOK, gin.H{
"name": login.Name,
"age": login.Age,
})
})
// 文件上传
r.POST("/upload", func(c *gin.Context) {
// 单文件上传
file, err := c.FormFile("upload_file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
// 上传文件到指定目录
if err := c.SaveUploadedFile(file, "./"+file.Filename); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
}
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"file": file.Filename,
})
})
// 请求重定向
// http重定向
r.GET("/redirect", func(c *gin.Context) {
// 重定向到指定URL
c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
})
// 路由重定向
r.GET("/redirect/:name", func(c *gin.Context) {
name := c.Param("name") // 获取URL路径参数
// 重定向到指定URL
c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("/user/%s", name))
})
// 路由和路由组
// 没有匹配路由
r.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{
"error": "没有匹配的路由",
})
})
// 路由组
userGroup := r.Group("/user")
{
// http://localhost:8080/user/info
userGroup.GET("/info", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "user info",
})
})
// http://localhost:8080/user/icon
userGroup.GET("/icon", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "user icon",
})
})
// 路由组嵌套
addGroup := userGroup.Group("/address")
{
// http://localhost:8080/user/address/province
addGroup.GET("province", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "province",
})
})
// http://localhost:8080/user/address/city
addGroup.GET("city", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "city",
})
})
}
}
// 中间件
// Gin中的中间件必须是一个gin.HandlerFunc类型
r.Use(cost()) // 使用中间件
// http://localhost:8080/middleware
r.GET("/middleware", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "middleware",
})
})
r.Run()
}