Gin企业网站定制开发是一个用编写的web框架。企业网站定制开发它是一个类似于martini企业网站定制开发但拥有更好性能的API框架, 企业网站定制开发由于使用了httprouter,企业网站定制开发速度提高了近40倍
Go企业网站定制开发世界里最流行的Web,上有32K+star。 企业网站定制开发基于开发的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
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框架中的路由使用的是这个库。
其基本原理就是构造一个路由地址的前缀树。
中间件
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\",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())。