golang基础:Gin框架进一步学习 | 青训营笔记

329 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记;

补上次:如果使用诸如http.StatusOK(就是200)之类的常量,则需要引入net/http包:import "net/http"

gin路由中响应数据

c.String()

//代码
r.GET("/string/:name", func(c *gin.Context) {
   var name string = c.Param("name")
   c.String(200, "值是:%v", name)
})
//访问路径
http://localhost/string/张三
//浏览器显示
值是:张三

c.JSON()

//代码
r.GET("/JSON/:name", func(c *gin.Context) {
   var name string = c.Param("name")
   c.JSON(200, map[string]interface{}{
      "message": "你好:" + name,
      "msg":     "200",
   })
})
//访问地址
http://localhost/JSON/张三
//浏览器显示
{"message":"你好:张三","msg":"200"}

map[string]interface{}{...}就相当于gin给我们提供的H函数,即gin.H{...}

json返回一个结构体:

//定义一个结构体
type user struct {
   Name  string
   power string//这个属性外界访问不到
   Age   string
}//结构体的属性名首字母必须大写,不然外界无法访问
//请求处理
r.GET("/json3", func(c *gin.Context) {
   a := &user{
      Name:  "张三",
      power: "big",
      Age:   "19",
   }
   c.JSON(200, a)
})
//浏览器访问
http://localhost/json3
{"Name":"张三","Age":"19"}

c.JSONP()

JSONP请求和JSON十分相似,JSONP与JSON的区别就是JSONP可以传入回调函数;JSONP主要用来处理跨域请求;

r.GET("/jsonp", func(c *gin.Context) {
   a := &user{
      Name:  "张三jsonp",
      Power: "jsonp",
      Age:   "jsonp",
   }
   c.JSONP(200, a)
})
r.Run(":80")

测试:

image.png

c.XML()

r.GET("/xml", func(c *gin.Context) {
   a := &user{
      Name:  "张三jsonp",
      Power: "jsonp",
      Age:   "jsonp",
   }
   c.XML(200, a)
})

image.png

c.HTML()

渲染模板

r.LoadHTMLGlob("templates/*") //先要加载所有模板文件
r.GET("/html", func(c *gin.Context) {
   c.HTML(200, "news.html", gin.H{
      "message": "后台数据",
   })
})

image.png 测试:

image.png

Gin HTML模板渲染

一个简单的渲染模板的例子:

//后端处理请求
r.LoadHTMLGlob("templates/*") //先要加载所有模板文件
r.GET("/", func(c *gin.Context) {
   a := &welcome{
      Title: "文章标题",
      Data:  "nil",
      News:  "xxxxx",
   }
   c.HTML(200, "index.html", gin.H{
      "title": "首页",
      "body":  a,
   })
})
//前端处理数据
<h1>{{.title}}</h1>
<p>
    {{.body.Title}}
</p>
<p>
    {{.body.Data}}
</p>
<p>
    {{.body.News}}
</p>

展示:

image.png 如果前端页面只有一层目录的话:

image.png 加载模板文件,只需r.LoadHTMLGlob("templates/*")即可; 但如果有多层:

image.png 就需要这样r.LoadHTMLGlob("templates/**/*")

如果不同文件目录下有相同名字的html页面,那么就需要在前端页面中配置模板名字:

<!--相当于给模板定义一个名字,define end成对出现-->
{{ define "admin/index.html" }}
<!--第一行-->
...
    页面内容
...
<!--最后一行-->
{{ end }}

后端渲染如下: c.HTML(200, "admin/index.html", gin.H{..}

也可以在前端将后台传过来的值"title": "首页",进行赋值,如下:

{{$t:=.title}}
<h4>
    {{$t}}
</h4>

自定义模板函数

可以通过一些自定义的模板函数直接在前端完成数据格式转换,比如一个日期格式转换的自定义模板函数,如下:

后端:

//定义日期转换函数
func UnixToTime(timestamp int) string {
   t := time.Unix(int64(timestamp), 0)
   //Unix创建一个本地时间,对应参数1和参数2表示的Unix时间
   //参数1为毫秒时间戳,参数2为纳秒时间戳
   return t.Format("2006-01-02 15:04:05")
   //格式化输出
}
...
//配置自定义模板函数(注意要放在加载模板之前)
r.SetFuncMap(template.FuncMap{
   "UnixToTime": UnixToTime,
})
r.LoadHTMLGlob("templates/**/*") //先要加载所有模板文件
...
r.GET("/html", func(c *gin.Context) {
   c.HTML(200, "newss.html", gin.H{
      "message": "后台数据",
      "time":    1729111111, //传递一个时间戳
   })
})
...
<!--前端使用-->
{{UnixToTime .time}}

显示如右: image.png

参数值绑定到结构体

.ShouldBind()强大的功能,它能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到指定的结构体对象。

get和post请求参数或表单数据绑定到结构体

//结构体
type UserInfo struct {
   Username string `json:"name" form:"username"`
   Password string `form:"password"`
} //json指定的是绑定到结构体后此结构体的属性名
//form指定的是请求参数名
...
r.GET("/getuser", func(c *gin.Context) {
//get与post一样,post只需将上面的“GET”改为“POST”
   user := &UserInfo{}
   err := c.ShouldBind(&user) 
   //将数据映射到user结构体中(注意括号里就相当于二级指针了)
   if err != nil {
      c.JSON(500, gin.H{
         "msg": "失败!!",
      })
   } else {
      c.JSON(200, user)
   }
})

get请求地址:http://localhost/getuser?username=张三&&password=12345

image.png