Go語言web框架Gin響應客戶端的方式
前言
Gin是一個用Go語言編寫的web框架。它是一個類似于martini但擁有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍。
如果你是性能和高效的追求者, 你會愛上Gin。Gin框架支持多種響應類型,包括字符串、JSON、XML和YAML等。
一、響應html頁面
響應頁面,就跟我們直接用http編程時的模板渲染差不多
1、我們首先定義一個存放模板文件的templates文件夾
然后在其內(nèi)部按照業(yè)務分別定義一個posts文件夾和一個users文件夾。 兩個文件夾中分別有posts/posts.html文件和users/users.html文件。

users/users.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的Go頁面</title>
</head>
<body>
<h1>users 感謝大家來到景天科技苑 Go語言全棧課</h1>
獲取傳入的數(shù)據(jù):
{{.msg}}
</body>
</html>
posts/posts.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的Go頁面</title>
</head>
<body>
<h1>posts 感謝大家來到景天科技苑 Go語言全棧課</h1>
獲取傳入的數(shù)據(jù):
{{.msg}}
</body>
</html>
2、讓程序進行頁面渲染和加載
Gin框架中使用 LoadHTMLGlob()或者 LoadHTMLFiles()方法進行HTML模板渲染
LoadHTMLGlob(pattern string):
這個方法接受一個模式(pattern),通常是一個通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
它會加載指定目錄下所有匹配該模式的文件作為模板。
這種方式適合于項目中模板文件較多,且都存放在同一個目錄下的情況。
LoadHTMLFiles(files …string):
這個方法接受一個文件名列表,你可以顯式地指定要加載的HTML模板文件。
它允許你加載項目中分散在不同目錄的模板文件,或者只加載特定的幾個模板文件。
這種方式提供了更細粒度的控制,你可以精確選擇哪些模板文件被加載。
//指定html模版路徑,這個方法接受一個模式(pattern),通常是一個通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
ginServer.LoadHTMLGlob("templates/*/*")
//使用ginServer.LoadHTMLFiles() 這個方法接受一個文件名列表,你可以顯式地指定要加載的HTML模板文件。
// func (engine *Engine) LoadHTMLFiles(files ...string)
//這種方式需要把文件名都列出來
//ginServer.LoadHTMLFiles("templates/posts/posts.html", "templates/users/posts.html")
// localhost:8088/hello
// 處理請求的函數(shù) *gin.Context
ginServer.GET("/posts/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "posts.html", gin.H{"msg": "這是后臺posts路徑返回的數(shù)據(jù)"})
})
//再寫個路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "users.html", gin.H{"msg": "這是后臺users路徑返回的數(shù)據(jù)"})
})
3、通過請求來響應頁面
使用c.HTML()方法,并需要加載HTML模板文件。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//以生產(chǎn)模式運行
//gin.SetMode(gin.ReleaseMode)
// 創(chuàng)建gin服務,創(chuàng)建一個默認的路由引擎ginServer。然后可以根據(jù)ginServer.GET,ginServer.ROST,ginServer.DELETE等內(nèi)置函數(shù)處理客戶端發(fā)來的http請求。
ginServer := gin.Default()
//指定html模版路徑,這個方法接受一個模式(pattern),通常是一個通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
ginServer.LoadHTMLGlob("templates/*")
//使用ginServer.LoadHTMLFiles() 這個方法接受一個文件名列表,你可以顯式地指定要加載的HTML模板文件。
// func (engine *Engine) LoadHTMLFiles(files ...string)
//這種方式需要把文件名都列出來
//ginServer.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html")
// localhost:8088/hello
// 處理請求的函數(shù) *gin.Context
ginServer.GET("/posts/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "index.tmpl", gin.H{"msg": "這是后臺posts路徑返回的數(shù)據(jù)"})
})
//再寫個路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "index.tmpl", gin.H{"msg": "這是后臺users路徑返回的數(shù)據(jù)"})
})
// 啟動HTTP服務,可以修改端口。默認是8080端口
err := ginServer.Run(":8088")
if err != nil {
return
}
}
4、啟動測試


5、靜態(tài)文件處理
當我們渲染的HTML文件中引用了靜態(tài)文件時,我們只需要按照以下方式在渲染頁面前調(diào)用gin.Static方法即可。
ginServer.Static(url string, path string)
url:URL前綴,客戶端通過這個前綴來訪問靜態(tài)文件。
path:靜態(tài)文件所在的目錄路徑。Gin 會將這個目錄下的文件映射到指定的URL前綴下。
文件結(jié)構(gòu)

package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//以生產(chǎn)模式運行
//gin.SetMode(gin.ReleaseMode)
// 創(chuàng)建gin服務,創(chuàng)建一個默認的路由引擎ginServer。然后可以根據(jù)ginServer.GET,ginServer.ROST,ginServer.DELETE等內(nèi)置函數(shù)處理客戶端發(fā)來的http請求。
ginServer := gin.Default()
//指定html模版路徑,這個方法接受一個模式(pattern),通常是一個通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
//ginServer.LoadHTMLGlob("templates/*/*")
//使用ginServer.LoadHTMLFiles() 這個方法接受一個文件名列表,你可以顯式地指定要加載的HTML模板文件。
// func (engine *Engine) LoadHTMLFiles(files ...string)
//這種方式需要把文件名都列出來
ginServer.LoadHTMLFiles("templates/posts/posts.html", "templates/users/users.html")
// 處理請求的函數(shù) *gin.Context
ginServer.GET("/posts/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "posts.html", gin.H{"msg": "這是后臺posts路徑返回的數(shù)據(jù)"})
})
//再寫個路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應html頁面使用c.HTML()
c.HTML(http.StatusOK, "users.html", gin.H{"msg": "這是后臺users路徑返回的數(shù)據(jù)"})
})
// 靜態(tài)資源
//引入css樣式文件 這樣需要訪問靜態(tài)資源的時候只需要在域名后面加上/static 就能訪問當前staticData目錄下的靜態(tài)資源
// 例如,如果客戶端請求 /static/css/main.css,Gin會嘗試從 ./staticData/css/main.css 文件中提供內(nèi)容。
ginServer.Static("/static", "staticData")
// 啟動HTTP服務,可以修改端口。默認是8080端口
err := ginServer.Run(":8088")
if err != nil {
return
}
}
前端html因日css靜態(tài)文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的Go頁面</title>
<link rel="stylesheet" href="/static/css/main.css" rel="external nofollow" >
</head>
<body>
<h1>posts 感謝大家來到景天科技苑 Go語言全棧課</h1>
獲取傳入的數(shù)據(jù):
{{.msg}}
</body>
</html>
瀏覽器請求,可見css樣式生效

二、響應字符串數(shù)據(jù)
Gin框架可以很方便地返回字符串類型的響應。以下是一個返回字符串響應的示例:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func StringResponse(c *gin.Context) {
c.String(http.StatusOK, "This is string response")
}
func main() {
r := gin.Default()
r.GET("/string", StringResponse)
r.Run(":8080")
}
在這個示例中,定義了一個StringResponse函數(shù),用于處理/string路徑的GET請求。當客戶端請求這個路徑時,服務器會返回字符串"This is string response"。
三、響應類型為JSON
Gin框架支持將結(jié)構(gòu)體或map類型的數(shù)據(jù)轉(zhuǎn)換為JSON格式的響應。
1. 返回普通數(shù)據(jù)類型
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 創(chuàng)建gin服務,創(chuàng)建一個默認的路由引擎ginServer。然后可以根據(jù)ginServer.GET,ginServer.ROST,ginServer.DELETE等內(nèi)置函數(shù)處理客戶端發(fā)來的http請求。
ginServer := gin.Default()
// localhost:8088/hello
// 處理請求的函數(shù) *gin.Context
ginServer.GET("/hello", func(c *gin.Context) {
// c.JSON:響應給客戶端JSON格式的數(shù)據(jù) func (c *Context) JSON(code int, obj any)
// gin.H : 參數(shù) key value
// gin.H 是一個便捷的快捷方式,你也可以直接使用 map[string]interface{} 來代替它
c.JSON(200, gin.H{"message": "Hello world!"})
})
// 啟動HTTP服務,可以修改端口。默認是8080端口
ginServer.Run(":8088")
}

2. 返回結(jié)構(gòu)體
(1) 不帶JSON標簽的結(jié)構(gòu)體
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func JsonResponse(c *gin.Context) {
// 定義的結(jié)構(gòu)體不帶json標簽
type UserInfo struct {
UserName string
Age int
}
user := UserInfo{UserName: "jingtian", Age: 20}
// 這里直接將不帶標簽的結(jié)構(gòu)體返回
c.JSON(http.StatusOK, user)
}
func main() {
r := gin.Default()
r.GET("/json", JsonResponse)
r.Run(":8080")
}
在這個示例中,定義了一個UserInfo結(jié)構(gòu)體,并將其實例化為user變量。然后,使用c.JSON(http.StatusOK, user)語句將user變量轉(zhuǎn)換為JSON格式的響應返回給客戶端。
響應的json字段名稱就是結(jié)構(gòu)體原本字段名

(2) 帶JSON標簽的結(jié)構(gòu)體
有時,我們希望結(jié)構(gòu)體字段在JSON響應中使用不同的名稱。這時,可以使用結(jié)構(gòu)體標簽(struct tag)來實現(xiàn)。
定義結(jié)構(gòu)體的時候,帶上json標簽,標簽可以與結(jié)構(gòu)體字段不一樣,這樣當我們返回結(jié)構(gòu)體的時候,返回的json字段是標簽字段
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func JsonResponse(c *gin.Context) {
// 定義結(jié)構(gòu)體的時候,帶上json標簽,標簽可以與結(jié)構(gòu)體字段不一樣,這樣當我們返回結(jié)構(gòu)體的時候,返回的json字段是標簽字段
type UserInfo struct {
UserName string `json:"user_name"`
Age int `json:"age"`
}
user := UserInfo{UserName: "景天帶標簽", Age: 20}
c.JSON(http.StatusOK, user)
}
func main() {
r := gin.Default()
r.GET("/json", JsonResponse)
r.Run(":8080")
}
結(jié)構(gòu)體的字段時username 而我們返回的json字符串中是我們定義的標簽user_name

在這個示例中,UserInfo結(jié)構(gòu)體的字段使用了json標簽,指定了在JSON響應中使用的名稱。因此,返回的JSON響應為{“user_name”:“json”,“age”:20}。
(3) 忽略某些字段
有時,我們可能不希望將結(jié)構(gòu)體的所有字段都包含在JSON響應中。這時,可以使用-標簽來忽略某些字段。
忽略該字段 使用- 標簽 這樣,響應的json中就不包含該字段
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func JsonResponse(c *gin.Context) {
type UserInfo struct {
UserName string `json:"user_name"`
Age int `json:"age"`
Password string `json:"-"` // 忽略該字段 使用- 標簽 這樣,響應的json中就不包含該字段
}
user := UserInfo{UserName: "景天忽略字段", Age: 20, Password: "secret"}
c.JSON(http.StatusOK, user)
}
func main() {
r := gin.Default()
r.GET("/json", JsonResponse)
r.Run(":8080")
}
在這個示例中,Password字段使用了-標簽,因此它不會被包含在JSON響應中。

(4) 返回map
除了結(jié)構(gòu)體之外,還可以使用map類型的數(shù)據(jù)來生成JSON響應。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func JsonResponse(c *gin.Context) {
// 定義map
data := map[string]interface{}{
"user_name": "景天map",
"age": 20,
}
//直接將map返回
c.JSON(http.StatusOK, data)
}
func main() {
r := gin.Default()
r.GET("/json", JsonResponse)
r.Run(":8080")
}

(5) 返回結(jié)構(gòu)體切片
有時候我們需要返回一個切片,里面是一個個的結(jié)構(gòu)體
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 創(chuàng)建gin服務
ginServer := gin.Default()
// localhost:8080/hello
// 處理請求的函數(shù) *gin.Context
ginServer.GET("/hello", func(c *gin.Context) {
//定義結(jié)構(gòu)體
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
//定義User類型的切片
users := make([]User, 2)
//給切片賦值
users[0] = User{"景天哥", "123456"}
users[1] = User{"趙日天", "895456"}
//響應結(jié)構(gòu)體切片
c.JSON(200, users)
})
// 啟動HTTP服務,可以修改端口
ginServer.Run(":8088")
}

四、響應類型為XML和YAML
除了JSON之外,Gin框架還支持將數(shù)據(jù)轉(zhuǎn)換為XML和YAML格式的響應。以下是一些示例:
1. 響應類型為XML
package main
import (
"encoding/xml"
"github.com/gin-gonic/gin"
"net/http"
)
func XmlResponse(c *gin.Context) {
type UserInfo struct {
XMLName xml.Name `xml:"user"`
UserName string `xml:"user_name"`
Age int `xml:"age"`
}
user := UserInfo{UserName: "xml", Age: 30}
// 使用c.XML返回xml格式
c.XML(http.StatusOK, user)
}
func main() {
r := gin.Default()
r.GET("/xml", XmlResponse)
r.Run(":8080")
}
注意:在這個示例中,需要使用encoding/xml包來處理XML數(shù)據(jù)。由于篇幅限制,這里省略了導入包的語句。

2. 響應類型為YAML
package main
import (
"github.com/gin-gonic/gin"
"gopkg.in/yaml.v3"
"net/http"
)
func YamlResponse(c *gin.Context) {
type UserInfo struct {
UserName string `yaml:"user_name"`
Age int `yaml:"age"`
}
user := UserInfo{UserName: "yaml", Age: 40}
//yaml序列化
// func Marshal(in interface{}) (out []byte, err error)
data, err := yaml.Marshal(user)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 通過c.Data響應為yaml數(shù)據(jù)
c.Data(http.StatusOK, "application/x-yaml", data)
}
func main() {
r := gin.Default()
r.GET("/yaml", YamlResponse)
r.Run(":8080")
}
在這個示例中,使用了gopkg.in/yaml.v3包(需要安裝這個包)來處理YAML數(shù)據(jù)。
yaml.Marshal(user)函數(shù)將user變量轉(zhuǎn)換為YAML格式的字節(jié)數(shù)組,然后使用c.Data方法將字節(jié)數(shù)組作為響應返回給客戶端。
同時,設置了響應頭Content-Type為application/x-yaml,以指示客戶端這是一個YAML格式的響應。
瀏覽器訪問該url就會下載yaml文件

以上就是Go語言web框架Gin響應客戶端的方式的詳細內(nèi)容,更多關(guān)于Go Gin響應客戶端的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go語言在請求http時加入自定義http header的方法
這篇文章主要介紹了go語言在請求http時加入自定義http header的方法,實例分析了Go語言http請求的原理與操作技巧,需要的朋友可以參考下2015-03-03
Golang使用ttl機制保存內(nèi)存數(shù)據(jù)方法詳解
ttl(time-to-live) 數(shù)據(jù)存活時間,我們這里指數(shù)據(jù)在內(nèi)存中保存一段時間,超過期限則不能被讀取到,與Redis的ttl機制類似。本文僅實現(xiàn)ttl部分,不考慮序列化和反序列化2023-03-03

