gin-web 框架

// ping
package main

import (
    "fmt"

    "net/http"

    "github.com/gin-gonic/gin"
)

func hello(c *gin.Context) {
    c.XML(200, gin.H{
        "message": "hey", "status": http.StatusOK,
    })
}

func main() {
    fmt.Println("Hello World!")

    r := gin.Default()
    // r.GET("/ping", func(c *gin.Context) {
    //  c.JSON(200, gin.H{
    //      "messge": "pong",
    //  })
    // })

    r.GET("/ping", hello)

    r.GET("/someJSON", func(c *gin.Context) {
        data := map[string]interface{}{
            "lang": "go",
            "tag":  "<br>",
        }
        c.AsciiJSON(http.StatusOK, data)
    })

    //------------

    r.Run(":8001")
}

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

// ping
package main

import (
    // "fmt"

    "net/http"

    "github.com/gin-gonic/gin"
)

func hello(c *gin.Context) {
    c.XML(200, gin.H{
        "message": "hey", "status": http.StatusOK,
    })
}

func main() {

    r := gin.Default()

    r1 := gin.Default()
    // r.GET("/ping", func(c *gin.Context) {
    //  c.JSON(200, gin.H{
    //      "messge": "pong",
    //  })
    // })

    r.GET("/ping", hello)

    r.GET("/someJSON", func(c *gin.Context) {
        data := map[string]interface{}{
            "lang": "go",
            "tag":  "<br>",
        }
        c.AsciiJSON(http.StatusOK, data)
    })

    r1.GET("/ping", hello)

    //------------
    r1.Run(":8002")

    r.Run(":8001")
}

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


image.png

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

// ping
package main

import (
    // "fmt"

    "net/http"

    "github.com/gin-gonic/gin"
)

func hello(c *gin.Context) {
    c.XML(200, gin.H{
        "message": "hey", "status": http.StatusOK,
    })
}

func main() {

    r := gin.Default()

    r1 := gin.Default()
    // r.GET("/ping", func(c *gin.Context) {
    //  c.JSON(200, gin.H{
    //      "messge": "pong",
    //  })
    // })

    r.GET("/ping", hello)

    r.GET("/someJSON", func(c *gin.Context) {
        data := map[string]interface{}{
            "lang": "go",
            "tag":  "<br>",
        }
        c.AsciiJSON(http.StatusOK, data)
    })

    // r1.GET("/ping", hello)

    //------------
    r1.Run(":8002")
    r1.GET("/ping", hello)
    r.Run(":8001")
}

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

image.png

Bind form-data request with custom struct

绑定对象

package main

import "github.com/gin-gonic/gin"

type StructA struct {
    FieldA string `form:"field_a"`
}

type StructB struct {
    NestedStruct StructA
    FieldB       string `form:"field_b"`
}

type StructC struct {
    NestedStructPointer *StructA
    FieldC              string `form:"field_c"`
}

type StructD struct {
    NestedAnonyStruct struct {
        FieldX string `form:""field_x`
    }
    FieldD string `form:"field_d"`
}

func GetDataB(c *gin.Context) {
    var b StructB
    c.Bind(&b)

    c.JSON(200, gin.H{"a": b.NestedStruct, "b": b.FieldB})
}

func GetDataC(c *gin.Context) {
    var b StructC
    c.Bind(&b)
    c.JSON(200, gin.H{"a": b.NestedStructPointer, "c": b.FieldC})
}

func GetDataD(c *gin.Context) {
    var b StructD
    c.Bind(&b)
    c.JSON(200, gin.H{"x": b.NestedAnonyStruct, "d": b.FieldD})
}

func main() {
    r := gin.Default()
    r.GET("/getb", GetDataB)
    r.GET("/getc", GetDataC)
    r.GET("/getd", GetDataD)

    r.Run()
}

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

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

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/gin-gonic/gin"
)

type Person struct {
    Name     string    `form:"name"`
    Address  string    `form:"address"`
    Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
}

func main() {
    route := gin.Default()
    route.Any("/testing", startPage)
    route.Run(":8085")
}

func startPage(c *gin.Context) {
    var person Person
    // If `GET`, only `Form` binding engine (`query`) used.
    // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
    // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
    if c.ShouldBind(&person) == nil {
        fmt.Println("----")
        log.Println(person.Name)
        log.Println(person.Address)
        log.Println(person.Birthday)
    }

    c.String(200, "Success")
}
// $ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"

bing uri

package main

import "github.com/gin-gonic/gin"

type Person struct {
    ID   string `uri:"id" binding:"required,uuid"`
    Name string `uri:"name" binding:"required"`
}

func main() {
    route := gin.Default()
    route.GET("/:name/:id", func(c *gin.Context) {
        var person Person
        if err := c.ShouldBindUri(&person); err != nil {
            c.JSON(400, gin.H{"msg": err})
            return
        }
        c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
    })

    route.Run(":8000")
    /*
    $ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
    $ curl -v localhost:8088/thinkerou/not-uuid
    */
}

buid the third-party package

package main

//go get github.com/jessevdk/go-assets-builder
import (
    "html/template"
    "io/ioutil"
    "net/http"
    "strings"

    "github.com/gin-gonic/gin"
    // "github.com/jessevdk/go-assets"
)

func main() {
    r := gin.New()

    t, err := loadTemplate()
    if err != nil {
        panic(err)
    }
    r.SetHTMLTemplate(t)

    r.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "/html/index.tmpl", nil)
    })
    r.Run(":8080")
}

// loadTemplate loads templates embedded by go-assets-builder
func loadTemplate() (*template.Template, error) {
    t := template.New("")
    for name, file := range Assets.Files {
        if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
            continue
        }
        h, err := ioutil.ReadAll(file)
        if err != nil {
            return nil, err
        }
        t, err = t.New(name).Parse(string(h))
        if err != nil {
            return nil, err
        }
    }
    return t, nil
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容