上一篇过于gin的内容
https://mp.csdn.net/mp_blog/creation/editor/131953861
CSDNhttps://mp.csdn.net/mp_blog/creation/editor/131953861
一、路由组
为了管理具有相同前缀的URL, 将拥有URL共同前缀的路由划分为一组
为了代码的阅读性,使用{}包裹相同组的路由不用{}包裹并不影响效果
1.1路由组
为了管理具有相同前缀的URL, 将拥有URL共同前缀的路由划分为一组
为了代码的阅读性,使用{}包裹相同组的路由不用{}包裹并不影响效果
上述的两个路由都是在shop这个组下
1.2路由组嵌套
1.3所有代码
package main
import (
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
// 如果指定的key 没有对应的值就使用默认值
username1 := ctx.DefaultQuery("username", "lisi")
// 根据key 获取值
username2 := ctx.Query("username")
address := ctx.Query("address")
// 返回JSON 字符串
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username1": username1,
"username2": username2,
"address": address,
})
}
// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {
// 获取参数值
username := ctx.Param("username")
address := ctx.Param("address")
// 数据返回
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
}
//=================================
// formParamsHandle 获取form表单提交数据
func formParamsHandle(ctx *gin.Context) {
// 获取不到值时就是用默认值
username1 := ctx.DefaultPostForm("username", "lisi")
username2 := ctx.PostForm("username")
address := ctx.PostForm("address")
// 以Json 字符串的形式返回
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username1": username1,
"username2": username2,
"address": address,
})
}
// json参数
// paramsJsonHandle 获取json字符串相关的参数
func paramsJsonHandle(ctx *gin.Context) {
// 获取request.Body() 中的数据(这里没有进行错误处理)
// 返回的是字节数组
dataBytes, _ := ctx.GetRawData()
// 定义一个map
var m map[string]interface{}
// 反序列化 别忘了&
_ = json.Unmarshal(dataBytes, &m)
// 数据返回
ctx.JSON(http.StatusOK, m)
}
//文件上传
/*
单个文件上传
文件上传接收的文件格式是: multipart/form-data
*/
// singleFileUploadHandle 当文件上传
func singleFileUploadHandle(ctx *gin.Context) {
// 获取文件
// 根据上传时的参数名获取上传的文件内容 --> 返回对象为 *multipart.FileHeader
fileHeader, err := ctx.FormFile("file")
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
// 保存文件内容
// 拼接文件名, 这里直接写死了
targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%s", fileHeader.Filename)
//targetFileName := fmt.Sprintf("%s", fileHeader.Filename)
// 将文件保存到指定的目录
err = ctx.SaveUploadedFile(fileHeader, targetFileName)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
} else {
ctx.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("%s upload success!", fileHeader.Filename),
})
}
}
//多文件上传
/**
多文件上传
*/
// multiFileUploadHandle 多文件上传
func multiFileUploadHandle(ctx *gin.Context) {
// form 是一个存储文件信息的结构体
/**
type Form struct {
Value map[string][]string
File map[string][]*FileHeader
*/
form, err := ctx.MultipartForm()
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
// 获取文件列表,并保存, 返回的是一个切片 []*FileHeader
files := form.File["file"]
for i, file := range files {
targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%d_%s", i, file.Filename)
err = ctx.SaveUploadedFile(file, targetFileName)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{
"message": err.Error(),
})
return
}
}
ctx.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("upload success!"),
})
}
// shuldbind数据的绑定的办法
// 使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
// 用户信息信息结构体
// 加上 binding:"required" 标签,说明该参数是必填的,如果不填就会报错
type UserInfo struct {
Username string `json:"username" form:"username" binding:"required"`
Address string `json:"address" form:"address" binding:"required"`
}
// 获取query参数
func queryHandle(ctx *gin.Context) {
var userInfo UserInfo
// 获取数据
err := ctx.ShouldBind(&userInfo)
if err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": userInfo.Username,
"address": userInfo.Address,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
}
func jsonHandle(ctx *gin.Context) {
var userInfo UserInfo
// 获取数据
err := ctx.ShouldBind(&userInfo)
if err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": userInfo.Username,
"address": userInfo.Address,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
}
func fromHandle(ctx *gin.Context) {
var userInfo UserInfo
// 获取数据
err := ctx.ShouldBind(&userInfo)
if err == nil {
ctx.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": userInfo.Username,
"address": userInfo.Address,
})
} else {
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
}
func main() {
// 创建默认路由
r := gin.Default()
//两种浏览器地址获取参数的办法
// 绑定路由规则 /user/search?username=zhangsan&address=北京
r.GET("/user/search", urlQueryHandle)
// 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
r.GET("/user/search/:username/:address", paramsPathHandle)
//========================表单提交方法======================
// 绑定路由规则
r.POST("/user/search", formParamsHandle)
//json
// 绑定路由规则
r.POST("/user/json", paramsJsonHandle)
//
// 绑定路由规则--文件上传
r.POST("/upload/single", singleFileUploadHandle)
绑定路由规则--多文件上传
r.POST("/upload/multi", multiFileUploadHandle)
//使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
// 绑定路由规则
r.GET("/user/query", queryHandle)
r.POST("/user/form", fromHandle)
r.POST("/user/jsons", jsonHandle)
//路由组的使用
// 绑定路由规则
shopGroup := r.Group("/shop")
{
// /shop/info
shopGroup.GET("/info", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "/shop/info")
})
// /shop/cart
shopGroup.GET("/cart", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "/shop/cart")
})
}
//路由组嵌套
// 绑定路由规则
shopGroup1 := r.Group("/shop1")
{
// shop/book
shopBookGroup1 := shopGroup1.Group("/book")
// shop/book/info
shopBookGroup1.GET("/info", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, "shop/book/info")
})
}
// 监听端口
r.Run(":9000")
}