gin框架
Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍
Go世界里最流行的Web框架,Github上有32K+star。 基于httprouter开发的Web框架。 中文文档齐全,简单易用的轻量级框架。
Gin的安装与使用
安装
命令行输入
go get -u github.com/gin-gonic/gin
使用,一个helloworld例子
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
// 1.创建路由
r := gin.Default()
// 2.绑定路由规则,执行的函数
// gin.Context,封装了request和response
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "hello World!")
})
// 3.监听端口,默认在8080
// Run("里面不指定端口号默认为8080")
r.Run(":8000")
}
将上面的代码保存并编译执行,然后使用浏览器打开127.0.0.1:8080/hello就能看到一串JSON字符串。
RESTful API
REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”。
简单来说,REST的含义就是客户端与Web服务器之间进行交互的时候,使用HTTP协议中的4个请求方法代表不同的动作。
- GET用来获取资源
- POST用来新建资源
- PUT用来更新资源
- DELETE用来删除资源。
r.GET("/book", func(c *gin.Context){
c.JSON(200, gin.H{
"method":"GET"
})
})
r.POST("/book",func(c *gin.Context){
c.JSON(200, gin.H{
"method":"POST"
})
})
r.PUT("/book",func(c *gin.Context){
c.JSON(200, gin.H{
"method":"PUT"
})
})
r.DELETE("/book",func(c *gin.Context){
c.JSON(200, gin.H{
"method":"DELETE"
})
})
只要API程序遵循了REST风格,那就可以称其为RESTful API。目前在前后端分离的架构中,前后端基本都是通过RESTful API来进行交互。
template
Go语言内置了文本模板引擎text/template和用于HTML文档的html/template。它们的作用机制可以简单归纳如下:
- 模板文件通常定义为.tmpl和.tpl为后缀(也可以使用其他的后缀),必须使用UTF8编码。
- 模板文件中使用{{和}}包裹和标识需要传入的数据。
- 传给模板这样的数据就可以通过点号(.)来访问,如果数据是复杂类型的数据,可以通过{ { .FieldName }}来访问它的字段。
- 除{{和}}包裹的内容外,其他内容均不做修改原样输出。
HTML渲染
gin框架中使用LoadHTMLGlob() 或者LoadHTMLFiles()方法进行HTML模板渲染
//r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html")
r.GET("/posts/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.html", gin.H{
"title": "posts/index",
})
})
r.GET("users/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.html", gin.H{
"title": "users/index",
})
})
静态文件处理、
当我们渲染的HTML文件中引用了静态文件时,我们只需要在渲染页面前调用gin.Static 方法即可
func main() {
r := gin.Default()
r.Static("/static", "./static")
r.LoadHTMLGlob("templates/**/*")
// ...
r.Run(":8080")
}
JSON渲染
func main(){
r := gin.Default()
//加载静态文件
//r.Static("/static","./statics")
r.GET("/someJSON",func(c *gin.Context){
//方式一:自己拼接json
c.JSON(http.StatusOK, gin.H{
"message": "Hello world",
})
})
r.GET("/moreJSON", func(c *gin.Context){
var msg struct{
Name string `json:"user"`
Message string
Age int
}
msg.Name="hhh"
msg.Message="Helloworld!"
msg.Age = 18
c.JSON(http.StatusOK,msg)
})
r.Run(":8080")
}
XML渲染
func main(){
r := gin.Default()
//加载静态文件
//r.Static("/static","./statics")
r.GET("/someXML",func(c *gin.Context){
//方式一:自己拼接json
c.XML(http.StatusOK, gin.H{
"message": "Hello world",
})
})
r.GET("/moreXML", func(c *gin.Context){
type msg struct{
Name string
Message string
Age int
}
var message msg
message.Name="hhh"
message.Message="Helloworld!"
message.Age = 18
c.XML(http.StatusOK,message)
})
r.Run(":8080")
}
除此之外还有YMAL渲染和上边的两种方法的使用方式相差不多
获取path参数
请求的参数通过URL路径传递
func main() {
//Default返回一个默认的路由引擎
r := gin.Default()
r.GET("/user/search/:username/:address", func(c *gin.Context) {
username := c.Param("username")
address := c.Param("address")
//输出json结果给调用方
c.JSON(http.StatusOK, gin.H{
"message": "ok",
"username": username,
"address": address,
})
})
r.Run(":8080")
}
参数绑定
为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。 下面的示例代码演示了 .ShouldBind()强大的功能,它能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到指定的结构体对象。
ShouldBind会按照下面的顺序解析请求中的数据完成绑定:
- 如果是 GET 请求,只使用 Form 绑定引擎(query)。
- 如果是 POST 请求,首先检查 content-type 是否为 JSON 或 XML,然后再使用 Form(form-data)。
重定向
HTTP重定向
HTTP 重定向很容易。 内部、外部重定向均支持。
r.GET("/test", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "http://www.sogo.com/")
})
路由重定向
路由重定向,使用HandleContext:
r.GET("/test", func(c *gin.Context) {
// 指定重定向的URL
c.Request.URL.Path = "/test2"
r.HandleContext(c)
})
r.GET("/test2", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"hello": "world"})
})
Gin路由
普通路由‘
r.Any("/test", func(c *gin.Context){...})
Any方法可以匹配所有的请求方法
为没有配置处理函数的路由添加处理程序,默认情况下它返回404代码,下面的代码为没有匹配到路由的请求都返回
views/404.html页面。
r.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusNotFound, "views/404.html", nil)
})
路由原理
Gin框架中的路由使用的是httprouter这个库。
其基本原理就是构造一个路由地址的前缀树。
中间件
Gin框架允许开发者在处理请求的过程中,加入用户自己的钩子(Hook)函数。这个钩子函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等。
定义中间件
Gin中的中间件必须是一个gin.HandlerFunc类型
func indexHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "index",
})
}
func main(){
r := gin.Default()
r.GET("index", indexHandler)
r.Run()
}
注册中间件
在gin框架中,我们可以为每个路由添加任意数量的中间件。
r.GET("index",m1,... indexHandler)
c.Next() 调用后续的处理函数
c.Abort() 阻止调用后续的处理函数
//计算执行程序花费的时间
func m1(c *gin.Context){
start := time.Now()
c.Next()
cost := time.Since(start)
fmt.Println("cost:%v\n",cost)
}
//
gin默认中间件
gin.Default()默认使用了Logger和Recovery中间件,其中:
- Logger中间件将日志写入gin.DefaultWriter,即使配置了GIN_MODE=release。
- Recovery中间件会recover任何panic。如果有panic的话,会写入500响应码。
如果不想使用上面两个默认的中间件,可以使用gin.New()新建一个没有任何默认中间件的路由。
gin中间件中使用goroutine
当在中间件或handler中启动新的goroutine时,不能使用原始的上下文(c *gin.Context),必须使用其只读副本(c.Copy())。
更多推荐
所有评论(0)