Gin的基本使用

  1. 安装:go get github.com/gin-gonic/gin
  2. 示例程序
package main

import (
  "fmt"
  "net/http"
  "path"

  "github.com/gin-gonic/gin"
)

type Account struct {
  Username string `json:"username"`
  Password string `json:"password"`
  Avatar   string `json:"avatar"`
}

type Response struct {
  Code ResponseCode `json:"code"`
  Err  string       `json:"err"`
  Data interface{}  `json:"data"`
}
type ResponseCode int32

// 响应码
const (
  ACCOUNT_NOT_EXISTS   ResponseCode = 10001
  ACCOUNT_LOGIN_FAILED ResponseCode = 10002
  USERNAME_ILEGAL      ResponseCode = 10003
  MULTIPART_FILE_ERROR ResponseCode = 10004
  UNKNOWN_URL          ResponseCode = 10005
)

func (code ResponseCode) String() string {
  switch code {
  case ACCOUNT_NOT_EXISTS:
  	return "用户不存在"
  case ACCOUNT_LOGIN_FAILED:
  	return "用户登录失败"
  case USERNAME_ILEGAL:
  	return "非法的用户名"
  case MULTIPART_FILE_ERROR:
  	return "文件上传错误"
  case UNKNOWN_URL:
  	return "未知路径"
  default:
  	return "未知响应码"
  }
}

func Ok(data interface{}) *Response {
  return &Response{http.StatusOK, "", data}
}

func Error(code ResponseCode, err string) *Response {
  return &Response{code, err, nil}
}

func main() {
  // 返回默认的路由引擎
  router := gin.Default()
  db := Account{"Acc01", "123456", "avatarurl.png"}

  // 普通的Get
  router.GET("/accounts", func(c *gin.Context) {
  	resp := Ok(db)
  	c.JSON(http.StatusOK, resp)
  })

  // 获取URL中的QueryParams username 和 password
  router.GET("/accounts/query", func(c *gin.Context) {
  	username := c.Query("username")
  	password := c.Query("password")
  	// 如果查不到该query param,则使用默认值
  	avatar := c.DefaultQuery("avatar", "avatarurl")
  	// 也可以这样:c.GetQuery("key") 只不过多了一个布尔类型返回值
  	account := &Account{username, password, avatar}
  	resp := Ok(account)
  	c.JSON(http.StatusOK, resp)
  })
  // 获取form表单参数
  router.POST("/accounts/login", func(c *gin.Context) {
  	username := c.PostForm("username")
  	password := c.PostForm("password")
  	if CheckAccount(username, password) {
  		c.JSON(http.StatusOK, Ok(nil))
  	} else {
  		c.JSON(http.StatusOK, Error(ACCOUNT_LOGIN_FAILED, ACCOUNT_LOGIN_FAILED.String()))
  	}
  	// 和上面一样也有 DefaultPostForm & GetPostForm
  })

  // 获取路径参数
  router.GET("/:username/:password", func(c *gin.Context) {
  	username := c.Param("username")
  	password := c.Param("password")
  	fmt.Println(username, password)
  	c.JSON(http.StatusOK, Ok(nil))
  })

  // RequestBody绑定结构体
  router.PUT("/accounts", func(c *gin.Context) {
  	var account Account
  	c.ShouldBind(&account)
  	fmt.Println(account)
  	c.JSON(http.StatusOK, Ok(nil))
  })

  // MultipartFile上传
  // 设置最大容量
  router.MaxMultipartMemory = 8 << 20 // 8 Mib
  router.POST("/upload", func(c *gin.Context) {
  	file, err := c.FormFile("file")
  	// 如果是多个文件的话,这里是c.MultipartForm(), 循环处理即可
  	if err != nil {
  		c.JSON(http.StatusOK, Error(MULTIPART_FILE_ERROR, MULTIPART_FILE_ERROR.String()))
  		return
  	}
  	filename := file.Filename
  	fileSavePath := path.Join("./", "images", filename)
  	// 将文件保存到本地
  	c.SaveUploadedFile(file, fileSavePath)
  	c.JSON(http.StatusOK, Ok(nil))
  })

  // HTTP重定向
  router.GET("/http/redirect", func(c *gin.Context) {
  	c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
  })
  // 路由重定向
  router.GET("/router/redirect", func(c *gin.Context) {
  	// 跳转到"/accounts"对应处理函数
  	c.Request.URL.Path = "/accounts"
  	router.HandleContext(c)
  })

  // router.Any支持所有HTTP请求方法
  // router.Any("/users", func(c *gin.Context) {
  // 	switch c.Request.Method {
  // 	case "GET":
  // 		//...
  // 	case "POST":
  // 		// ...
  // 	}
  // })

  // 用户访问不存在地址
  router.NoRoute(func(c *gin.Context) {
  	c.JSON(http.StatusOK, Error(UNKNOWN_URL, UNKNOWN_URL.String()))
  	// 或者也可以返回一个页面
  })
  // 以上都是普通的单个路由
  // 下面是路由组
  accountGroup := router.Group("/accounts")
  accountGroup.POST("/register", func(c *gin.Context) {}) // /accounts/register
  accountGroup.DELETE("/:id", func(c *gin.Context) {})    // /accounts/:id
  // 路由组也是支持嵌套的

  //!Gin中间件:类似于JavaWeb的拦截器,允许开发者在处理请求的过程中,加入用户自定义的钩子函数,适合处理一些公共业务,比如登录认证,权限校验,日志记录等
  //Gin的中间件必须是一个gin.HandleFunc类型
  // 比如下面这个URL 指定它先要经过登录中间件
  router.GET("/accounts/infos", LoginInterceptor, func(c *gin.Context) {
  	fmt.Println("Get Accounts Infos...")
  })
  /**
  	GinWeb项目一般目录结构:
  	controller 不是放路由注册,而是请求控制逻辑
  	dao or repo 持久层封装
  	service or logic 业务处理
  	model or entity 实体相关
  **/
  // !也可以全局注册中间件
  router.Use(LoginInterceptor)
  // 启动服务 默认8080
  router.Run(":9090")
}

//! 登录中间件(拦截器)
func LoginInterceptor(c *gin.Context) {
  fmt.Println("登录拦截...")
  // 放行 调用后续处理函数
  c.Next()
  //!执行完后续处理函数还是回回到这里,也可以进行一些处理完成后的操作:日志,性能监控之类的
  // 阻止调用后续处理函数
  // c.Abort()
}

func CheckAccount(u string, p string) bool {
  return true
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值