这是我参与「第五届青训营 」伴学笔记创作活动的第5天
处理请求的方式
//默认在8080端口
r := gin.Default()
//传入路径,对应的响应的函数
//GET/POST/DELETE/PUT
r.GET("/hello", sayhello)
r.Run(":9090")
返回json
向json中传入数据的方式有多种。
func sayhello(c *gin.Context) {
//方法1:使用map
data := map[string]interface{}
//方法2:使用gin自定义的集合H,一种快速的无需指明类型的map
//data:= gin.H{"name":"小明",}
//方法3:使用自定义的结构体,结构体属性必须大写或使用标签注明(类似GORM标签注明字段),否则会出现序列化的问题。
//data: = user{"小明"}
//参数为状态码,数据
c.JSON(http.StatusOK, data)
}
获取请求参数
跟请求像相关的参数往往都要从参数中 *gin.Context中获取。 例: localhost:8080/web?query=小明&age=18
r=c.Default()
r.GET("/web", response)
//获取参数
func response(c *gin.Context){
name1:=c.Query("query")
//DefaultQuery可以在取不到参数时使用默认值
name2:=c.DefaultQuery("query","默认名称")
//GetQuery函数有两个返回值,第一个为取参数结果,第二个为一个布尔值.取不到值时会返回false。
name,ok := c.GetQuery("query")
}
获取form表单的参数
name:=c.PostForm("username")
password=c.PostForm("password")
与DefaultQuery()类似,获取表单参数同样有DefaultPostForm()和GetPostForm()的方式。
获取URI路径参数
例如: localhost:8080/male/jack 对应的响应方式:
r.GET("/:sex/:name",func (c *gin.Context){
name := c.Param("name")
key := c.Param("age")
})
参数的映射
利用ShoudBind()方法绑定给结构体直接赋值,结构体中属性要大写并且用标签注明对应参数名。
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
type UserInfo struct {
Username string `form:"username" json:"username"`
Password string `form:"password" json:"username"`
}
func main() {
r := gin.Default()
r.POST("/form", func(c *gin.Context) {
var u UserInfo
// 参数绑定
err := c.ShouldBind(&u)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error: ": err.Error(),
})
} else {
fmt.Println("%#v\n", u)
c.JSON(http.StatusOK, gin.H{
"status": "ok",
})
}
})
r.Run()
}
文件上传
//从form表单中获取文件
file,err :=c.FormFile("image")
if err!=nil{
//错误处理
}else{
//保存文件到本地
dst:=path.Join("./",file.Filename)
c.SaveUploadedFile(file,dst)
}
//多个文件上传时,将c.FormFile()函数换为:
//res即为存有文件的集合。
f, err := c.MultipartForm()
res = f.File["files"]
请求重定向
HTTP重定向
func main() {
r := gin.Default()
r.GET("/baidu", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com")
})
r.Run(":8080")
}
路由重定向
func main() {
r := gin.Default()
r.GET("/a", func(c *gin.Context) {
//把请求的地址设为/b
c.Request.URL.Path = "/b"
r.HandleContext(c)
})
r.GET("/b", func(c *gin.Context) {
//处理不存在的请求地址可以使用r.NoRoute()
})
r.Run(":8080")
}
路由组
路由组即为几个请求提供公共的前缀。类似于java在controller上注释的请求路径。
v1 := router.Group("/v1") {
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
中间件
golang中的中间件类似于Java中拦截器的概念,可以对一些广泛使用的功能做出实现,如日志记录,权限验证等等。
定义一个中间件
func m1(c *gin.Context) {
fmt.Println("m1执行")
//调用后续中间件
c.Next()
//c.Abort() 阻止后续中间件运行
fmt.Println("m1结束")
}
添加中间件到控制器中
方式1:可以在路由里直接添加作为函数,只对该路由有效,同时决定了调用的顺序。 方式2:通过r.Use()的方法进行全局设置。 方式3:可以同时向路由组中注册中间件。
func main() {
r := gin.Default()
//r.Use(m1)
r.GET("/user", m1, func(c *gin.Context) {
})
r.Run(":8080")
}
常用中间件写法
func authMiddleware(doCheck bool) gin.HandlerFunc {
//一些准备工作 如连接数据库
return func(c *gin.Context) {
if doCheck {
//一些其他逻辑
c.Next()
} else {
c.Abort()
}
}
}