这是我参与「第三届青训营 -后端场」笔记创作活动的第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")
测试:
c.XML()
r.GET("/xml", func(c *gin.Context) {
a := &user{
Name: "张三jsonp",
Power: "jsonp",
Age: "jsonp",
}
c.XML(200, a)
})
c.HTML()
渲染模板
r.LoadHTMLGlob("templates/*") //先要加载所有模板文件
r.GET("/html", func(c *gin.Context) {
c.HTML(200, "news.html", gin.H{
"message": "后台数据",
})
})
测试:
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>
展示:
如果前端页面只有一层目录的话:
加载模板文件,只需
r.LoadHTMLGlob("templates/*")即可;
但如果有多层:
就需要这样
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}}
显示如右:
参数值绑定到结构体
.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