1. // ping
  2. package main
  3. import (
  4. "fmt"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. )
  8. func hello(c *gin.Context) {
  9. c.XML(200, gin.H{
  10. "message": "hey", "status": http.StatusOK,
  11. })
  12. }
  13. func main() {
  14. fmt.Println("Hello World!")
  15. r := gin.Default()
  16. // r.GET("/ping", func(c *gin.Context) {
  17. // c.JSON(200, gin.H{
  18. // "messge": "pong",
  19. // })
  20. // })
  21. r.GET("/ping", hello)
  22. r.GET("/someJSON", func(c *gin.Context) {
  23. data := map[string]interface{}{
  24. "lang": "go",
  25. "tag": "<br>",
  26. }
  27. c.AsciiJSON(http.StatusOK, data)
  28. })
  29. //------------
  30. r.Run(":8001")
  31. }

突然有个贱想法:如果main类中使用两个端口会怎么样

  1. // ping
  2. package main
  3. import (
  4. // "fmt"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. )
  8. func hello(c *gin.Context) {
  9. c.XML(200, gin.H{
  10. "message": "hey", "status": http.StatusOK,
  11. })
  12. }
  13. func main() {
  14. r := gin.Default()
  15. r1 := gin.Default()
  16. // r.GET("/ping", func(c *gin.Context) {
  17. // c.JSON(200, gin.H{
  18. // "messge": "pong",
  19. // })
  20. // })
  21. r.GET("/ping", hello)
  22. r.GET("/someJSON", func(c *gin.Context) {
  23. data := map[string]interface{}{
  24. "lang": "go",
  25. "tag": "<br>",
  26. }
  27. c.AsciiJSON(http.StatusOK, data)
  28. })
  29. r1.GET("/ping", hello)
  30. //------------
  31. r1.Run(":8002")
  32. r.Run(":8001")
  33. }

查看控制台,发现只有8002端口启动成功后不再往下执行。
image.png

想法二:方法处理函数放到Run 下面会怎么样

  1. // ping
  2. package main
  3. import (
  4. // "fmt"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. )
  8. func hello(c *gin.Context) {
  9. c.XML(200, gin.H{
  10. "message": "hey", "status": http.StatusOK,
  11. })
  12. }
  13. func main() {
  14. r := gin.Default()
  15. r1 := gin.Default()
  16. // r.GET("/ping", func(c *gin.Context) {
  17. // c.JSON(200, gin.H{
  18. // "messge": "pong",
  19. // })
  20. // })
  21. r.GET("/ping", hello)
  22. r.GET("/someJSON", func(c *gin.Context) {
  23. data := map[string]interface{}{
  24. "lang": "go",
  25. "tag": "<br>",
  26. }
  27. c.AsciiJSON(http.StatusOK, data)
  28. })
  29. // r1.GET("/ping", hello)
  30. //------------
  31. r1.Run(":8002")
  32. r1.GET("/ping", hello)
  33. r.Run(":8001")
  34. }

结果:8082端口映射的ping 方法404了
image.png

Bind form-data request with custom struct

绑定对象

  1. package main
  2. import "github.com/gin-gonic/gin"
  3. type StructA struct {
  4. FieldA string `form:"field_a"`
  5. }
  6. type StructB struct {
  7. NestedStruct StructA
  8. FieldB string `form:"field_b"`
  9. }
  10. type StructC struct {
  11. NestedStructPointer *StructA
  12. FieldC string `form:"field_c"`
  13. }
  14. type StructD struct {
  15. NestedAnonyStruct struct {
  16. FieldX string `form:""field_x`
  17. }
  18. FieldD string `form:"field_d"`
  19. }
  20. func GetDataB(c *gin.Context) {
  21. var b StructB
  22. c.Bind(&b)
  23. c.JSON(200, gin.H{"a": b.NestedStruct, "b": b.FieldB})
  24. }
  25. func GetDataC(c *gin.Context) {
  26. var b StructC
  27. c.Bind(&b)
  28. c.JSON(200, gin.H{"a": b.NestedStructPointer, "c": b.FieldC})
  29. }
  30. func GetDataD(c *gin.Context) {
  31. var b StructD
  32. c.Bind(&b)
  33. c.JSON(200, gin.H{"x": b.NestedAnonyStruct, "d": b.FieldD})
  34. }
  35. func main() {
  36. r := gin.Default()
  37. r.GET("/getb", GetDataB)
  38. r.GET("/getc", GetDataC)
  39. r.GET("/getd", GetDataD)
  40. r.Run()
  41. }

测试 第一个正常参数,二三测试参数有多或者有不对应的,均未出现程序异常,参数接受异常处理做的挺好。

curl http://localhost:8080/getb?field_a=hello&field_b=world&field_c=22
curl http://localhost:8080/getb?field_a=hello&field_b=world
curl http://localhost:8080/getb?field_ab=hello&field_b=world&field_c=22

bind query string or post data

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "time"
  6. "github.com/gin-gonic/gin"
  7. )
  8. type Person struct {
  9. Name string `form:"name"`
  10. Address string `form:"address"`
  11. Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
  12. }
  13. func main() {
  14. route := gin.Default()
  15. route.Any("/testing", startPage)
  16. route.Run(":8085")
  17. }
  18. func startPage(c *gin.Context) {
  19. var person Person
  20. // If `GET`, only `Form` binding engine (`query`) used.
  21. // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
  22. // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
  23. if c.ShouldBind(&person) == nil {
  24. fmt.Println("----")
  25. log.Println(person.Name)
  26. log.Println(person.Address)
  27. log.Println(person.Birthday)
  28. }
  29. c.String(200, "Success")
  30. }
  31. // $ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"

bing uri

  1. package main
  2. import "github.com/gin-gonic/gin"
  3. type Person struct {
  4. ID string `uri:"id" binding:"required,uuid"`
  5. Name string `uri:"name" binding:"required"`
  6. }
  7. func main() {
  8. route := gin.Default()
  9. route.GET("/:name/:id", func(c *gin.Context) {
  10. var person Person
  11. if err := c.ShouldBindUri(&person); err != nil {
  12. c.JSON(400, gin.H{"msg": err})
  13. return
  14. }
  15. c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
  16. })
  17. route.Run(":8000")
  18. /*
  19. $ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
  20. $ curl -v localhost:8088/thinkerou/not-uuid
  21. */
  22. }

buid the third-party package

  1. package main
  2. //go get github.com/jessevdk/go-assets-builder
  3. import (
  4. "html/template"
  5. "io/ioutil"
  6. "net/http"
  7. "strings"
  8. "github.com/gin-gonic/gin"
  9. // "github.com/jessevdk/go-assets"
  10. )
  11. func main() {
  12. r := gin.New()
  13. t, err := loadTemplate()
  14. if err != nil {
  15. panic(err)
  16. }
  17. r.SetHTMLTemplate(t)
  18. r.GET("/", func(c *gin.Context) {
  19. c.HTML(http.StatusOK, "/html/index.tmpl", nil)
  20. })
  21. r.Run(":8080")
  22. }
  23. // loadTemplate loads templates embedded by go-assets-builder
  24. func loadTemplate() (*template.Template, error) {
  25. t := template.New("")
  26. for name, file := range Assets.Files {
  27. if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
  28. continue
  29. }
  30. h, err := ioutil.ReadAll(file)
  31. if err != nil {
  32. return nil, err
  33. }
  34. t, err = t.New(name).Parse(string(h))
  35. if err != nil {
  36. return nil, err
  37. }
  38. }
  39. return t, nil
  40. }