Gin on the third day
1. Form parameters
Forms are transmitted as POST requests, and there are four common HTTP transmission formats:
- application/json
- application/x-www-form-urlencoded
- application/xml
- multipart/form-data
Form parameters can be obtained via the PostForm() method, which by default parses x-www-form-urlencoded or FROm-data format parameters
Let’s start by writing a simple submission form with a basic username and password
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo1</title>
</head>
<body>
<form action="http://localhost:8080/form" method="post" action="application/x-www-form-urlencoded">User name:<input type="text" name="username" placeholder="Please enter your user name"> <br>
密 Code:<input type="password" name="userpassword" placeholder="Please enter your password."> <br>
<input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code
Here, the action of our form is set to post path later
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// Form parameters
func main(a){
r:=gin.Default()
r.POST("/form".func(c *gin.Context) {
types:=c.DefaultPostForm("type"."post")
// The key name corresponds to the HTML page attribute name
username:=c.PostForm("username")
password:=c.PostForm("userpassword")
c.String(http.StatusOK,fmt.Sprintf("username:%s,password:%s,types:%s",username,password,types))
})
r.Run()
}
Copy the code
2. Upload files
2.1 Uploading a Single File
The multipart/form-data format is used for file uploading. Gin file uploading is similar to the native NET/HTTP method, except that GIN encapsulates the native request into C. Test. Again, start with an HTML page that uploads a single file
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo2</title>
</head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">Uploading files:<input type="file" name="file" >
<input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code
The gin implementation then receives and saves the form file
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
// Upload a single file
func main(a){
r:=gin.Default()
/ / 8 < < 20 8 * 2 ^ 20 = 8 m
r.MaxMultipartMemory=8<<20
r.POST("/upload".func(c *gin.Context){
file,err:=c.FormFile("file")
iferr! =nil{
c.String(500."Error uploading file")
}
c.SaveUploadedFile(file,file.Filename)
c.String(http.StatusOK,file.Filename+"Upload successful")
})
r.Run()
}
Copy the code
What if I want to limit uploads to PNG and no other file formats? We can implement functions that limit the type of file uploads ourselves
Select the file type from HEADERS and determine if it matches. The modified code looks like this
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
// Upload a single file
func main(a) {
r := gin.Default()
/ / 8 < < 20 8 * 2 ^ 20 = 8 m
r.MaxMultipartMemory = 8 << 20
r.POST("/upload".func(c *gin.Context) {
_,headers, err := c.Request.FormFile("file")
iferr ! =nil {
c.String(500."Error uploading file")}if headers.Header.Get("Content-Type")! ="image/png"{
c.String(500."Upload PNG files only")
return
}
c.SaveUploadedFile(headers, "./imgs/"+headers.Filename)
c.String(http.StatusOK, headers.Filename+"Upload successful")
})
r.Run()
}
Copy the code
2.2 Uploading multiple Files
Multi-file upload means that you can upload multiple files at once, which makes it easier for the uploader. (Some websites can only upload one file at a time, which is really uncomfortable.)
There is no special change to the uploaded page, just add a multiple to the Input upload form
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo2</title>
</head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">Uploading files:<input type="file" name="files" multiple>
<input type="submit" value="Submit">
</form>
</body>
</html>
Copy the code
Mostly back-end operations, but luckily gin has a multipart form module (encapsulating mime/multipart, all parsed)
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// Multiple file uploads
func main(a) {
r := gin.Default()
r.MaxMultipartMemory = 8 << 20
r.POST("/upload".func(c *gin.Context) {
form, err := c.MultipartForm()
iferr ! =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,"./res/"+file.Filename); err! =nil{
c.String(http.StatusBadRequest,fmt.Sprintf("upload err %s",err.Error()))
return
}
}
c.String(http.StatusOK,fmt.Sprintf("upload %d files".len(files)))
})
r.Run()
}
Copy the code
3. 404 pages
Often when we’re developing, we don’t know what kind of URL the user is going to type in the future, so we need to set up 404 pages, which are pages that can’t be found, right
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
// Set 404 NOT FOUND
func main(a){
r:=gin.Default()
r.GET("/user".func(c *gin.Context){
name:=c.DefaultQuery("name"."shelgi")
c.String(http.StatusOK,fmt.Sprintf("hello %s",name))
})
// When accessing an unknown route
r.NoRoute(func(c *gin.Context){
c.String(http.StatusNotFound,"404 NOT FOUND")
})
r.Run()
}
Copy the code
Let’s go to the routing interface we’ve set up
Try again the screen where no route is set
Look at the NoRoute ()
It’s a method of the engine that passes in a processor function that returns 404 by default
These processor functions are defined at the top
Looking at engines, blind guessing is a structure with many methods and properties
Sure enough, you guessed right. An engine is an instance of a framework that contains multiplexing routes, middleware, and Settings. You can create an engine instance using either New() or Default(). This is why we always start with gin-.default (), in other words we can use gin-.new () instead.
Learning about Gin
After three days of learning, Gin is not very difficult to learn according to my experience, but there are not enough relevant materials in the community or on the Internet. I have been exposed to GO before, and I have read basic classic books and web-related books, but I did not get involved in the specific framework. In order to really get to know Gin, I have reviewed the basic knowledge of GO again, which I think is very useful when I am learning Gin.
To learn Gin, we have to learn to read and understand the source code by ourselves, because of its few resources and the lack of detailed official documents. This is why my blog adds many source code explanations in addition to reproducing the contents of the documents, which also requires us to have a certain degree of mastery of GO. So the basic language knowledge needs to be stable before learning any framework (especially for me, who often uses many languages in a day, so I can keep my mind clear).
I will also continue to write the Gin column, trying to clarify some of the details, from implementation to source code parsing in the hope of helping later learners. In addition, I have my eye on GoFrame, an enterprise-level framework developed in China, and the official documentation is very rich. After Gin, I should start to use GoFrame, like Flask vs Django?