Go語言web框架Gin響應(yīng)客戶端的方式
前言
Gin是一個(gè)用Go語言編寫的web框架。它是一個(gè)類似于martini但擁有更好性能的API框架, 由于使用了httprouter,速度提高了近40倍。
如果你是性能和高效的追求者, 你會(huì)愛上Gin。Gin框架支持多種響應(yīng)類型,包括字符串、JSON、XML和YAML等。
一、響應(yīng)html頁面
響應(yīng)頁面,就跟我們直接用http編程時(shí)的模板渲染差不多
1、我們首先定義一個(gè)存放模板文件的templates文件夾
然后在其內(nèi)部按照業(yè)務(wù)分別定義一個(gè)posts文件夾和一個(gè)users文件夾。 兩個(gè)文件夾中分別有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、讓程序進(jìn)行頁面渲染和加載
Gin框架中使用 LoadHTMLGlob()或者 LoadHTMLFiles()方法進(jìn)行HTML模板渲染
LoadHTMLGlob(pattern string):
這個(gè)方法接受一個(gè)模式(pattern),通常是一個(gè)通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
它會(huì)加載指定目錄下所有匹配該模式的文件作為模板。
這種方式適合于項(xiàng)目中模板文件較多,且都存放在同一個(gè)目錄下的情況。
LoadHTMLFiles(files …string):
這個(gè)方法接受一個(gè)文件名列表,你可以顯式地指定要加載的HTML模板文件。
它允許你加載項(xiàng)目中分散在不同目錄的模板文件,或者只加載特定的幾個(gè)模板文件。
這種方式提供了更細(xì)粒度的控制,你可以精確選擇哪些模板文件被加載。
//指定html模版路徑,這個(gè)方法接受一個(gè)模式(pattern),通常是一個(gè)通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
ginServer.LoadHTMLGlob("templates/*/*")
//使用ginServer.LoadHTMLFiles() 這個(gè)方法接受一個(gè)文件名列表,你可以顯式地指定要加載的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) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "posts.html", gin.H{"msg": "這是后臺(tái)posts路徑返回的數(shù)據(jù)"})
})
//再寫個(gè)路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "users.html", gin.H{"msg": "這是后臺(tái)users路徑返回的數(shù)據(jù)"})
})
3、通過請求來響應(yīng)頁面
使用c.HTML()方法,并需要加載HTML模板文件。
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//以生產(chǎn)模式運(yùn)行
//gin.SetMode(gin.ReleaseMode)
// 創(chuàng)建gin服務(wù),創(chuàng)建一個(gè)默認(rèn)的路由引擎ginServer。然后可以根據(jù)ginServer.GET,ginServer.ROST,ginServer.DELETE等內(nèi)置函數(shù)處理客戶端發(fā)來的http請求。
ginServer := gin.Default()
//指定html模版路徑,這個(gè)方法接受一個(gè)模式(pattern),通常是一個(gè)通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
ginServer.LoadHTMLGlob("templates/*")
//使用ginServer.LoadHTMLFiles() 這個(gè)方法接受一個(gè)文件名列表,你可以顯式地指定要加載的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) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "index.tmpl", gin.H{"msg": "這是后臺(tái)posts路徑返回的數(shù)據(jù)"})
})
//再寫個(gè)路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "index.tmpl", gin.H{"msg": "這是后臺(tái)users路徑返回的數(shù)據(jù)"})
})
// 啟動(dòng)HTTP服務(wù),可以修改端口。默認(rèn)是8080端口
err := ginServer.Run(":8088")
if err != nil {
return
}
}
4、啟動(dòng)測試


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

package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//以生產(chǎn)模式運(yùn)行
//gin.SetMode(gin.ReleaseMode)
// 創(chuàng)建gin服務(wù),創(chuàng)建一個(gè)默認(rèn)的路由引擎ginServer。然后可以根據(jù)ginServer.GET,ginServer.ROST,ginServer.DELETE等內(nèi)置函數(shù)處理客戶端發(fā)來的http請求。
ginServer := gin.Default()
//指定html模版路徑,這個(gè)方法接受一個(gè)模式(pattern),通常是一個(gè)通配符(如"*.html"),用于匹配目錄中的所有HTML模板文件。
// func (engine *Engine) LoadHTMLGlob(pattern string)
//ginServer.LoadHTMLGlob("templates/*/*")
//使用ginServer.LoadHTMLFiles() 這個(gè)方法接受一個(gè)文件名列表,你可以顯式地指定要加載的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) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "posts.html", gin.H{"msg": "這是后臺(tái)posts路徑返回的數(shù)據(jù)"})
})
//再寫個(gè)路徑
ginServer.GET("/users/index", func(c *gin.Context) {
//響應(yīng)html頁面使用c.HTML()
c.HTML(http.StatusOK, "users.html", gin.H{"msg": "這是后臺(tái)users路徑返回的數(shù)據(jù)"})
})
// 靜態(tài)資源
//引入css樣式文件 這樣需要訪問靜態(tài)資源的時(shí)候只需要在域名后面加上/static 就能訪問當(dāng)前staticData目錄下的靜態(tài)資源
// 例如,如果客戶端請求 /static/css/main.css,Gin會(huì)嘗試從 ./staticData/css/main.css 文件中提供內(nèi)容。
ginServer.Static("/static", "staticData")
// 啟動(dòng)HTTP服務(wù),可以修改端口。默認(rèn)是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樣式生效

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

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

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

在這個(gè)示例中,UserInfo結(jié)構(gòu)體的字段使用了json標(biāo)簽,指定了在JSON響應(yīng)中使用的名稱。因此,返回的JSON響應(yīng)為{“user_name”:“json”,“age”:20}。
(3) 忽略某些字段
有時(shí),我們可能不希望將結(jié)構(gòu)體的所有字段都包含在JSON響應(yīng)中。這時(shí),可以使用-標(biāo)簽來忽略某些字段。
忽略該字段 使用- 標(biāo)簽 這樣,響應(yīng)的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:"-"` // 忽略該字段 使用- 標(biāo)簽 這樣,響應(yīng)的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")
}
在這個(gè)示例中,Password字段使用了-標(biāo)簽,因此它不會(huì)被包含在JSON響應(yīng)中。

(4) 返回map
除了結(jié)構(gòu)體之外,還可以使用map類型的數(shù)據(jù)來生成JSON響應(yīng)。
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)體切片
有時(shí)候我們需要返回一個(gè)切片,里面是一個(gè)個(gè)的結(jié)構(gòu)體
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 創(chuàng)建gin服務(wù)
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"}
//響應(yīng)結(jié)構(gòu)體切片
c.JSON(200, users)
})
// 啟動(dòng)HTTP服務(wù),可以修改端口
ginServer.Run(":8088")
}

四、響應(yīng)類型為XML和YAML
除了JSON之外,Gin框架還支持將數(shù)據(jù)轉(zhuǎn)換為XML和YAML格式的響應(yīng)。以下是一些示例:
1. 響應(yīng)類型為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")
}
注意:在這個(gè)示例中,需要使用encoding/xml包來處理XML數(shù)據(jù)。由于篇幅限制,這里省略了導(dǎo)入包的語句。

2. 響應(yīng)類型為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響應(yīng)為yaml數(shù)據(jù)
c.Data(http.StatusOK, "application/x-yaml", data)
}
func main() {
r := gin.Default()
r.GET("/yaml", YamlResponse)
r.Run(":8080")
}
在這個(gè)示例中,使用了gopkg.in/yaml.v3包(需要安裝這個(gè)包)來處理YAML數(shù)據(jù)。
yaml.Marshal(user)函數(shù)將user變量轉(zhuǎn)換為YAML格式的字節(jié)數(shù)組,然后使用c.Data方法將字節(jié)數(shù)組作為響應(yīng)返回給客戶端。
同時(shí),設(shè)置了響應(yīng)頭Content-Type為application/x-yaml,以指示客戶端這是一個(gè)YAML格式的響應(yīng)。
瀏覽器訪問該url就會(huì)下載yaml文件

以上就是Go語言web框架Gin響應(yīng)客戶端的方式的詳細(xì)內(nèi)容,更多關(guān)于Go Gin響應(yīng)客戶端的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
GO 函數(shù)式選項(xiàng)模式(Functional Options Pattern)
Option模式支持傳遞多個(gè)參數(shù),并且在參數(shù)個(gè)數(shù)、類型發(fā)生變化時(shí)保持兼容性,任意順序傳遞參數(shù),下面給大家介紹GO 函數(shù)式選項(xiàng)模式(Functional Options Pattern)的相關(guān)知識,感興趣的朋友一起看看吧2021-10-10
Go語言使用Redis和Etcd實(shí)現(xiàn)高性能分布式鎖
這篇文章主要為大家介紹了Go語言使用Redis實(shí)現(xiàn)高性能分布式鎖示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
如何控制Go編碼JSON數(shù)據(jù)時(shí)的行為(問題及解決方案)
今天來聊一下我在Go中對數(shù)據(jù)進(jìn)行 JSON 編碼時(shí)遇到次數(shù)最多的三個(gè)問題以及解決方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-02-02
Go語言使用Goroutine并發(fā)打印的項(xiàng)目實(shí)踐
本文通過并發(fā)打印任務(wù)案例,講解Go語言Goroutine的使用、同步控制及高并發(fā)優(yōu)勢,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-08-08

