(Go Gin)Gin學習筆記(四)Gin的數據渲染和中間件的使用:數據渲染、返回JSON、淺.JSON()源碼、中間件、Next()方法

1. 數據渲染

1.1 各種數據格式的響應

  • json、結構體、XML、YAML類似于java的properties、ProtoBuf

1.1.1 返回JSON

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.POST("/demo", func(res *gin.Context) {res.JSON(http.StatusOK, gin.H{"message": "success",})})r.Run(":8080")
}

1.1.2 返回結構體

r.GET("/demo", func(res *gin.Context) {var obj struct {name stringage  int8}obj.age = 1obj.name = "張三"res.JSON(http.StatusOK, obj)
})

1.1.3 XML 和 YAML

// 3.XML
r.GET("/someXML", func(c *gin.Context) {c.XML(200, gin.H{"message": "abc"})
})
// 4.YAML響應
r.GET("/someYAML", func(c *gin.Context) {c.YAML(200, gin.H{"name": "zhangsan"})
})

1.1.4 淺淺扒一下源碼

進入res.JSON函數里面看一下

res.JSON(http.StatusOK, obj)
func (c *Context) JSON(code int, obj any) {c.Render(code, render.JSON{Data: obj})
}
  • (c *Context) 代表可以被Context類型調用
  • (code int, obj any) 傳入參數,狀態碼和返回對象

它本身內部再次封裝了一層提供給Render類型

func (c *Context) Render(code int, r render.Render) {c.Status(code)if !bodyAllowedForStatus(code) {r.WriteContentType(c.Writer)c.Writer.WriteHeaderNow()return}if err := r.Render(c.Writer); err != nil {// Pushing error to c.Errors_ = c.Error(err)c.Abort()}
}

進入Render里面,可以看到

  • (code int, r render.Render) 參數進行了更改,傳入了render包下的Render類型

可以看一下Render這個接口

type Render interface {// Render writes data with custom ContentType.Render(http.ResponseWriter) error// WriteContentType writes custom ContentType.WriteContentType(w http.ResponseWriter)
}

接口還提供了一個可以修改ContentType的方法

if !bodyAllowedForStatus(code) {r.WriteContentType(c.Writer)c.Writer.WriteHeaderNow()return
}
  • bodyAllowedForStatus()進行了判斷
func bodyAllowedForStatus(status int) bool {switch {case status >= 100 && status <= 199:return falsecase status == http.StatusNoContent:return falsecase status == http.StatusNotModified:return false}return true
}

判斷了傳入的狀態碼是否符合正確的狀態碼,并返回

  • 當bodyAllowedForStatus()判斷為錯誤狀態碼時

    會在返回對象中寫入ContentType內容

? c.Writer.WriteHeaderNow()還會寫入文本流中

再看一下其他返回的類型;例如XML

func (c *Context) XML(code int, obj any) {c.Render(code, render.XML{Data: obj})
}

在內部封裝時,只是標注了不同的render類型

1.2 重定向

訪問/demo地址時,將頁面重定向跳轉至其他頁面

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.GET("/demo", func(c *gin.Context) {c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")})r.Run(":8080")
}

2. 中間件

2.1 全局中間件

  • 所有請求都經過此中間件
package mainimport ("github.com/gin-gonic/gin""log""time"
)func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {t := time.Now()log.Println("中間件開始運行:", t)c.Set("middle_1", "中間件1執行結束")status := c.Writer.Status()log.Println("中間件執行結束:", status)t2 := time.Since(t)log.Println("耗時:", t2)}
}func main() {r := gin.Default()// 注冊中間件r.Use(MiddleWare())r.GET("/demo", func(c *gin.Context) {// 獲得內容m, _ := c.Get("middle_1")log.Println("中間件接收參數:", m)c.JSON(200, gin.H{"中間件接收參數:": m})})r.Run(":8080")
}

測試:http://localhost:8080/demo

返回結果:

[GIN-debug] Listening and serving HTTP on :8080
2025/04/29 00:12:34 中間件開始運行: 2025-04-29 00:12:34.5992889 +0800 CST m=+1.770059901
2025/04/29 00:12:34 中間件執行結束: 200
2025/04/29 00:12:34 耗時: 11.5258ms
2025/04/29 00:12:34 中間件接收參數: 中間件1執行結束
[GIN] 2025/04/29 - 00:12:34 | 200 |     11.5258ms |             ::1 | GET      "/demo"

gin 使用r.Use()來注冊一個組件

  • 在注冊組件時,我們需要規定函數的返回類型,這才能讓gin知道這是什么組件
func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {t := time.Now()log.Println("中間件開始運行:", t)c.Set("middle_1", "中間件1執行結束")status := c.Writer.Status()log.Println("中間件執行結束:", status)t2 := time.Since(t)log.Println("耗時:", t2)}
}
  • 這里MiddleWare()函數規定了返回類型是 gin.HandlerFunc ,這就代表這個函數是一個處理類

2.1.1 Next() 方法

我們在正常注冊中間件時,會打斷原有的運行流程,但是你可以在中間件函數內部添加Next()方法,這樣可以讓原有的運行流程繼續執行,當原有的運行流程結束后再回來執行中間件內部的內容

package mainimport ("github.com/gin-gonic/gin""log""time"
)func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {t := time.Now()log.Println("中間件開始運行:", t)// 開啟正常執行流程c.Next()c.Set("middle_1", "中間件1執行結束")status := c.Writer.Status()log.Println("中間件執行結束:", status)t2 := time.Since(t)log.Println("耗時:", t2)}
}func main() {r := gin.Default()// 注冊中間件r.Use(MiddleWare())r.GET("/demo", func(c *gin.Context) {// 獲得內容m, _ := c.Get("middle_1")log.Println("中間件接收參數:", m)c.JSON(200, gin.H{"中間件接收參數:": m})})r.Run(":8080")
}

測試:http://localhost:8080/demo

返回結果:

[GIN-debug] Listening and serving HTTP on :8080
2025/04/29 00:14:14 中間件開始運行: 2025-04-29 00:14:14.5697461 +0800 CST m=+2.981609901
2025/04/29 00:14:14 中間件接收參數: <nil>
2025/04/29 00:14:14 中間件執行結束: 200
2025/04/29 00:14:14 耗時: 14.0262ms
[GIN] 2025/04/29 - 00:14:14 | 200 |     14.0262ms |             ::1 | GET      "/demo"

可以看到使用next后,正常執行流程中并沒有獲得到中間件設置的值

2.2 局部中間件

package mainimport ("github.com/gin-gonic/gin""log""time"
)func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {t := time.Now()log.Println("中間件開始運行:", t)c.Set("middle_1", "中間件1執行結束")status := c.Writer.Status()log.Println("中間件執行結束:", status)t2 := time.Since(t)log.Println("耗時:", t2)}
}func main() {r := gin.Default()// 局部中間件-在為一個請求添加執行函數時即可掛載中間件r.GET("/demo", MiddleWare(), func(c *gin.Context) {// 獲得內容m, _ := c.Get("middle_1")log.Println("中間件接收參數:", m)c.JSON(200, gin.H{"中間件接收參數:": m})})r.Run(":8080")
}
  • 為你想給哪一個請求掛載中間件,直接在對應的請求中添加中間件函數即可

3. ??GoGin框架——前文鏈接

Gin框架學習參考網站:gin框架·Go語言中文文檔

  • (Go Gin)基于Go的WEB開發框架,GO Gin是什么?怎么啟動?本文給你答案
  • (Go Gin)Gin學習筆記(二):路由配置、基本路由、表單參數、上傳單個文件、上傳多個文件、淺扒路由原理

    (Go Gin)Gin學習筆記(三):數據解析和綁定,結構體分析,包括JSON解析、form解析、URL解析,區分綁定的Bind方法

4. 💕👉博客專欄

  • Golang專欄-包含基礎、Gin、Goam等知識
  • 云原生專欄-包含k8s、docker等知識
  • 從0開始學習云計算-華為HCIP證書
  • JUC專欄-帶你快速領悟JUC的知識!
  • JVM專欄-深入Java虛擬機,理解JVM的原理
  • 基于Java研究 數據結構與算法-包含貪心算法、加權圖、最短路徑算法等知識
  • Docker專欄-上手熱門容器技術Docker
  • SpringBoot專欄-學習SpringBoot快速開發后端
  • 項目管理工具的學習-設計技術:Maven、Git、Gradle等相關管理工具
  • JavaSE-全面了解Java基礎
  • JS專欄-使用JS作的一部分實例~
  • 使用CSS所作的一部分案例

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78959.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78959.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78959.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實驗:串口通信

/************************************************* * AT89C52 串口通信實驗&#xff08;實用修正版&#xff09; * 特點&#xff1a; * 1. 解決所有編譯警告 * 2. 保持代碼簡潔 * 3. 完全功能正常 ************************************************/ #include <re…

智駕賽道的諾曼底登陸,Momenta上海車展雄起

作者 |蘆葦 編輯 |德新 今年的上海車展依舊熱鬧非凡&#xff0c;但火熱的車市背后也是暗流涌動。尤其對智駕供應商而言&#xff0c;「智駕平權」帶動了解決方案大量上車&#xff0c;各大主機廠紛紛選定各自的主要供應商&#xff0c;這也意味著賽道機會越發收斂。 正如汽車品牌…

Java 事務詳解

目錄 一、事務的基本概念1.1 什么是事務?1.2 事務的 ACID 特性二、Java 事務管理的實現方式2.1 JDBC 事務管理2.2 Spring 事務管理2.2.1 添加 Spring 依賴2.2.2 配置 Spring 事務管理2.2.3 使用 Spring 事務注解三、事務隔離級別四、最佳實踐4.1 盡量縮小事務范圍4.2 合理選擇…

DirectX12(D3D12)基礎教程七 深度模板視圖\剔除\謂詞

本章主要講遮擋&#xff0c;作者認為比較復雜有難度的知識點&#xff0c;作為基礎教程不會深入講解。 GPU渲染管線 主要包括以下階段 輸入裝配&#xff08;IA&#xff09;&#xff1a;讀取頂點數據 &#xff0c;定義頂點數據結構頂點著色&#xff08;VS&#xff09;&#xf…

溫補晶振(TCXO)穩定性優化:從實驗室到量產的關鍵技術

在現代通信、航空航天、5G基站等對頻率穩定性要求極高的領域&#xff0c;溫補晶振&#xff08;TCXO&#xff09;扮演著不可或缺的角色。其穩定性直接影響系統的性能與可靠性&#xff0c;因此&#xff0c;對TCXO穩定性優化技術的研究與實踐至關重要。 一、溫度補償算法&#xff…

C++,設計模式,【建造者模式】

文章目錄 通俗易懂的建造者模式&#xff1a;手把手教你造電腦一、現實中的建造者困境二、建造者模式核心思想三、代碼實戰&#xff1a;組裝電腦1. 產品類 - 電腦2. 抽象建造者 - 裝機師傅3. 具體建造者 - 電競主機版4. 具體建造者 - 辦公主機版5. 指揮官 - 裝機總控6. 客戶端使…

前端基礎之《Vue(13)—重要API》

重要的API 一、nextTick() 1、寫法 Vue.$nextTick()或者this.$nextTick() 原因&#xff1a; set操作代碼是同步的&#xff0c;但是代碼背后的行為是異步的。set操作修改聲明式變量&#xff0c;觸發re-render生成新的虛擬DOM&#xff0c;進一步執行diff運算&#xff0c;找到…

Windows 中搭建 browser-use WebUI 1.4

目錄 1. 背景介紹2. 搭建過程3. 補充 1. 背景介紹 背景&#xff1a;想要在 Windows 中復現 browser-use WebUI pickle反序列化漏洞&#xff0c;該漏洞在 v1.7 版本中已經修復&#xff0c;所以需要搭建 小于 1.7 版本的環境&#xff0c;我這里搭建的是 1.4 版本。 項目地址&am…

【數據通信完全指南】從物理層到協議棧的深度解析

目錄 1. 通信技術演進與核心挑戰1.1 從電報到5G的技術變遷1.2 現代通信系統的三大瓶頸 2. 通信系統架構深度解構2.1 OSI七層模型運作原理2.2 TCP/IP協議棧實戰解析 3. 物理層關鍵技術實現3.1 信號調制技術演進路線3.2 信道復用方案對比 4. 數據傳輸可靠性保障4.1 CRC校驗算法數…

CMD與PowerShell:Windows命令行工具的對比與使用指南

CMD與PowerShell&#xff1a;Windows命令行工具的對比與使用指南 文章目錄 CMD與PowerShell&#xff1a;Windows命令行工具的對比與使用指南引言1. CMD&#xff08;命令提示符&#xff09;簡介1.1 什么是CMD&#xff1f;1.2 CMD的特點1.3 常用CMD命令示例1.4 CMD的優勢與局限 2…

93. 后臺線程與主線程更新UI Maui例子 C#例子

在.NET MAUI開發中&#xff0c;多線程是常見的需求&#xff0c;但UI更新必須在主線程上執行。今天&#xff0c;我們來探討一個簡單而優雅的解決方案&#xff1a;MainThread.InvokeOnMainThreadAsync。 一、背景 在跨平臺應用開發中&#xff0c;后臺線程常用于執行耗時操作&am…

海思正式公開了星閃BS21E的SDK

今天海思正式在Gitee平臺發布了BS21E的SDK&#xff1a;fbb_bs2x: fbb_bs2x代碼倉為支持bs21e解決方案SDK。技術論壇&#xff1a;https://developers.hisilicon.com/forum/0133146886267870001 fbb_bs2x代碼倉為支持bs21e解決方案SDK&#xff0c;該SDK包從統一開發平臺FBB&#…

QML學習:使用QML實現抽屜式側邊欄菜單

文章目錄 前言一、環境配置二、實現步驟三、示例完整代碼四、注意事項總結 前言 最近在進行QML的學習&#xff0c;發現一個比較有意思的交互設計&#xff1a;抽屜式側邊欄菜單&#xff0c;出于開發實戰需求&#xff0c;最終實現了一個支持手勢拖拽、彈性動畫、蒙層效果和??智…

峰終定律——AI與思維模型【85】

一、定義 峰終定律思維模型是指人們對一段經歷的評價主要取決于這段經歷中的高峰時刻&#xff08;無論是正向的還是負向的&#xff09;以及結束時的感受&#xff0c;而不是整個經歷的平均感受。也就是說&#xff0c;如果在一段體驗的高峰和結尾階段給人們留下積極、強烈的印象…

【補題】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du

題意&#xff1a;給出n&#xff0c;d&#xff0c;m三個值&#xff0c;分別代表&#xff0c;有多少個值ai&#xff0c;使用超過m的ai&#xff0c;需要禁言d天&#xff0c;如果不足也能使用&#xff0c;m代表區分點&#xff0c;問能得到最大的值有多少。 思路&#xff1a; …

單片機與上位機串口通信:原理、應用與實踐

注&#xff1a;本文為 “單片機與上位機串口通信” 相關文章合輯。 略作重排&#xff0c;未整理去重。 如有內容異常&#xff0c;請看原文。 單片機與上位機的串行通信 饕餮 tt 于 2019 - 12 - 06 14:47:19 發布 寫在前面 本文主要記錄單片機通過 TXD、RXD 與上位機進行數據…

996引擎-人物模型(UIModel):創建內觀時裝備偏移問題

996引擎-人物模型(UIModel):創建內觀時裝備偏移問題 創建 人物模型(UIModel)問題參考資料創建 人物模型(UIModel) 90、91 是自定義劍甲的穿戴位置,因為需求只需要顯示劍甲,所以下面創建人物模型時,只給了劍甲的id、特效。 function Controller:updateUI()-- 自定義收拾…

Python小程序:上班該做點摸魚的事情

系統提醒 上班會忘記一些自己的事&#xff0c;所以你需要在上班的的時候突然給你彈窗&#xff0c;你就知道要做啥了 源碼 這里有一個智能家居項目可以看看(開源) # -*- coding:utf-8 -*- """ 作者:YTQ 日期: 2025年04日29 21:51:24 """ impor…

centos安裝部署配置kafka

1、解壓到目錄 tar -zxvf kafka_2.13-2.8.2.tgz -C /usr/local/kafka2.進入目錄 cd /usr/local/kafka/kafka_2.13-2.8.23.查看版本&#xff08;驗證是否已解壓&#xff09; bin/kafka-topics.sh --version4.修改配置&#xff0c;注意&#xff1a;此配置中有一個默認的zookee…

深?理解指針(7)

1.函數指針變量的創建 在x86環境下&#xff1a; 我們發現&#xff1a;以函數是有地址的&#xff0c;函數名就是函數的地址&#xff0c;當然也可以通過& 函數名 的?式獲得函數的地址。 如果我們要將函數的地址存放起來&#xff0c;就得創建函數指針變量咯&#xff0c;函數…