前言
在看是今天的内容之前,我们收先来探究一下:什么是Web应用工作的原理?当然这个问题其实论述起来是很麻烦的,但是我们将它无限的缩小,其实可以简化为一个C/S模型,客户端(Client)负责发送请求,服务端(Server,也就使我们的Web应用)接收 请求,来进行相关的操作,模型如下:
而今天我们所要介绍的就是服务端如何进行相关数据的响应
Http响应码
在HTTP协议定义了一组状态码,用于指示服务器对请求的处理结果,这里我们只对比较常见的做一下简单介绍,想要了解更多的话大家可以参考下面这篇博文:
HTTP状态码大全(常见 HTTP Status Code 含义查询)
- 200:成功,
- 404:资源未找到,
- 500:服务器内部错误
Json
在上一篇文章中我们利用gin框架实现了与浏览器的交互,在网页上面打印了hello world
,这是一个很典型的响应字符串,而在响应Json中,除了一些细节以外本质上其实还是类似的,比如下面这个Json响应的代码:
package main import ( "github.com/gin-gonic/gin" ) type UserInfo struct { Name string `json:"user"` Age int `json:"age"` } func toJson(c *gin.Context) { //响应Json的函数 user := UserInfo{ Name: "Fengxu", Age: 23, } c.JSON(200, user) } func main() { r := gin.Default() r.GET("/", toJson) err := r.Run(":8080") if err != nil { return } }
运行我们会看到页面上出现了Json字符串:
关于Json响应的细节
- Get函数
gin 包提供了 GET 函数来定义处理 HTTP GET 请求的路由,我们来看一下Get函数的签名:
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes { return group.handle(http.MethodGet, relativePath, handlers) }
这里有两个参数:
1.path:path 是该路由的路径,可以包含参数,例如上面的路径就是:http://127.0.0.1:8080/
2.handlers:路由处理函数,这里用了可变参数,所以这里其实可以有多个路由处理函数
- 这里拓展一下Json响应的两种不同写法:
- 将信息存储到map中
func toJson(c *gin.Context) { //响应Json的函数 usermap := map[string]string{ "user": "张三", "age": "18", } c.JSON(200, usermap) }
- 使用原始Json字符串
func toJson(c *gin.Context) { //响应Json的函数 c.JSON(200, gin.H{"user": "zhangsan", "age": 18}) }
- 如果我们有些消息不想显示在网页上面,可以想下面这样写:
package main import ( "github.com/gin-gonic/gin" ) type UserInfo struct { Name string `json:"user"` Age int `json:"age"` password string `json:"-"` } func toJson(c *gin.Context) { //响应Json的函数 user := UserInfo{ Name: "luoyu", Age: 18, password: "123456", } c.JSON(200, user) } func main() { r := gin.Default() r.GET("/", toJson) err := r.Run(":8080") if err != nil { return } }
运行结果:
xml与yaml
- Xml
package main import ( "github.com/gin-gonic/gin" ) func toXml(c *gin.Context) { //响应Json的函数 c.XML(200, gin.H{"user": "zhangsan", "age": 18}) } func main() { r := gin.Default() r.GET("/", toXml) err := r.Run(":8080") if err != nil { return } }
- Yaml
package main import ( "github.com/gin-gonic/gin" ) func toYAml(c *gin.Context) { //响应Json的函数 c.YAML(200, gin.H{"user": "zhangsan", "age": 18}) } func main() { r := gin.Default() r.GET("/", toYAml) err := r.Run(":8080") if err != nil { return } }
- YAML
package main import ( "github.com/gin-gonic/gin" ) func toYAml(c *gin.Context) { //响应Json的函数 c.YAML(200, gin.H{"user": "zhangsan", "age": 18}) } func main() { r := gin.Default() r.GET("/", toYAml) err := r.Run(":8080") if err != nil { return } }
HTML
HTML与上面的几个不同,接下来我给大家演示一下如何加载一个HTML模版:
首先我们在项目里面创建一个template
文件夹,然后我们创建index.html
,尝试写一个简单的页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> hello {{.username}} </body> </html>
然后我们尝试响应HTML:
package main import ( "github.com/gin-gonic/gin" ) func toHtml(c *gin.Context) { //响应Json的函数 c.HTML(200, "index.html", gin.H{"username": "fengxu"}) } func main() { r := gin.Default() r.LoadHTMLGlob("template/*") r.GET("/", toHtml) err := r.Run(":8080") if err != nil { return } }
运行结果为:
注意: 我们在使用c.HTML
函数签,要先加载模版文件:
func (engine *Engine) LoadHTMLFiles(files ...string) //加载单/多个html文件 func (engine *Engine) LoadHTMLGlob(pattern string) //加载该路径下所有的html文件
文件响应
- 单个文件响应
这里我准备了一张照片,我们可以尝试来将它和浏览器交互,让我们可以在网页上看到它:
首先我在项目文件夹中创建source
文件夹,表示这里存放一些相关资源,
然后我们可以使用StaticFile
来实现上述操作,代码如下:
package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.StaticFile("/file", "Source/static/img.png") err := r.Run(":8080") if err != nil { return } }
运行结果为;
- 响应指定文件夹里面的内容
有时候我们只希望Source
里面指定文件夹可以访问,但是其他的不能访问,我们可以这样来写,首先我们创建一个文件夹public
,在里面创建a.txt
,内容如下:
aguihylsywiop;s1yho hjgiuzoagiusu1i
然后我们尝试来加载这个文件夹:
package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { r := gin.Default() //r.StaticFile("/file", "Source/static/img.png") r.StaticFS("/static", http.Dir("Source/public")) err := r.Run(":8080") if err != nil { return } }
这样我们指定文件就可以访问了:
补充:
函数解析:
- StaticFile:
- StaticFile 函数用于将单个静态文件映射到指定的 URL 路径上。
- 它接受两个参数:URL 路径和文件路径。
- StaticFS 函数
- 用于将一个目录中的所有静态文件映射到指定的 URL 路径上。
- 它接受两个参数:URL 路径和目录路径。