表单参数
表单参数传输为post请求,http常见的传输格式为四种
- application/json
- application/x-www-form-urlencoded
- application/xml
- multipart/form-data
表单参数可以通过PostForm()方法获取,该方法默认解析的是x-www-form-urlencoded或from-data格式的参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">
用户名:<input type="text" name="username" placeholder="请输入你的用户名"> <br>
密 码:<input type="password" name="userpassword" placeholder="请输入你的密码"> <br>
<input type="submit" value="提交">
</form>
</body>
</html>
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.POST("/form", func(ctx *gin.Context) {
types := ctx.DefaultPostForm("type", "post")
username := ctx.PostForm("username")
password := ctx.PostForm("userpassword")
ctx.String(http.StatusOK, fmt.Sprintf("username:%s,password:%s,type:%s",
username, password, types))
})
r.Run()
}
上传文件
- multipart/form-data格式用于文件上传
- gin文件上传与原生的net/http方法类似,不同在于gin把原生的request封装到c.Request中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
上传文件:<input type="file" name="file" >
<input type="submit" value="提交">
</form>
</body>
</html>
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
//限制上传最大尺寸
r.MaxMultipartMemory = 8 << 20
r.POST("/upload", func(ctx *gin.Context) {
file, err := ctx.FormFile("file")
if err != nil {
ctx.String(500, "上传图片出错")
}
//保存文件
ctx.SaveUploadedFile(file, file.Filename)
//返回输出消息
ctx.String(http.StatusOK, file.Filename)
})
r.Run()
}
限制上传指定文件大小以及文件类型
package main
import (
"fmt"
"log"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.POST("/upload", func(c *gin.Context) {
_, headers, err := c.Request.FormFile("file")
if err != nil {
log.Printf("Error when try to get file: %v", err)
}
//headers.Size 获取文件大小
if headers.Size > 1024*1024*2 {
fmt.Println("文件太大了")
return
}
//headers.Header.Get("Content-Type")获取上传文件的类型
if headers.Header.Get("Content-Type") != "image/png" {
fmt.Println("只允许上传png图片")
return
}
c.SaveUploadedFile(headers, "./video/"+headers.Filename)
c.String(http.StatusOK, headers.Filename)
})
r.Run()
}
上传多个文件
package main
import (
"github.com/gin-gonic/gin"
"net/http"
"fmt"
)
// gin的helloWorld
func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 限制表单上传大小 8MB,默认为32MB
r.MaxMultipartMemory = 8 << 20
r.POST("/upload", func(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get err %s", err.Error()))
}
// 获取所有图片
files := form.File["files"]
// 遍历所有图片
for _, file := range files {
// 逐个存
if err := c.SaveUploadedFile(file, file.Filename); err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("upload err %s", err.Error()))
return
}
}
c.String(200, fmt.Sprintf("upload ok %d files", len(files)))
})
//默认端口号是8080
r.Run(":8000")
}
路由组
routes group是为了管理一些相同的URL
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func login(ctx *gin.Context) {
name := ctx.DefaultQuery("name", "yangchao")
ctx.String(200, fmt.Sprintf("hello %s\n", name))
}
func submit(ctx *gin.Context) {
name := ctx.DefaultQuery("name", "hcie")
ctx.String(200, fmt.Sprintf("hello %s\n", name))
}
func main() {
//创建路由
//默认使用了2个中间件Logger(),Recovery()
r := gin.Default()
//路由组1处理get请求
v1 := r.Group("/v1")
//{}是书写规范
{
v1.GET("/login", login)
v1.GET("/submit", submit)
}
v2 := r.Group("/v2")
{
v2.POST("/login", login)
v2.POST("/submit", submit)
}
r.Run()
}
测试
实现404页面
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/user", func(ctx *gin.Context) {
//指定默认值
name := ctx.DefaultQuery("name", "yangchao")
ctx.String(http.StatusOK, fmt.Sprintf("hello %s", name))
})
//指定404
r.NoRoute(func(ctx *gin.Context) {
ctx.String(http.StatusNotFound, "404 no found 1123131")
})
r.Run()
}