最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言結(jié)合validator包實(shí)現(xiàn)表單驗(yàn)證

 更新時(shí)間:2024年11月21日 09:39:22   作者:左詩右碼  
在現(xiàn)代?Web?開發(fā)中,表單驗(yàn)證和錯誤處理是至關(guān)重要的環(huán)節(jié),本文將演示如何使用?Go?語言的?Gin?框架結(jié)合?validator?包,實(shí)現(xiàn)高級的表單驗(yàn)證功能,需要的可以參考下

在現(xiàn)代 Web 開發(fā)中,表單驗(yàn)證和錯誤處理是至關(guān)重要的環(huán)節(jié),尤其是在多語言環(huán)境下。

本文將通過一個實(shí)際的示例,演示如何使用 Go 語言的 Gin 框架結(jié)合 validator 包,實(shí)現(xiàn)高級的表單驗(yàn)證功能,并且支持國際化(i18n)的錯誤信息提示。

背景與需求

假設(shè)我們正在開發(fā)一個用戶注冊功能,需要對用戶提交的信息進(jìn)行嚴(yán)格的驗(yàn)證。例如,用戶名不能為空、郵箱格式必須正確、密碼和確認(rèn)密碼必須一致、用戶年齡應(yīng)在合理范圍內(nèi)(如 1 到 130 歲),并且日期字段不能早于當(dāng)前日期。除此之外,系統(tǒng)還需要根據(jù)用戶的語言偏好提供相應(yīng)語言的錯誤提示信息。

代碼示例

我們將從以下幾個方面展開:

  • 表單數(shù)據(jù)的結(jié)構(gòu)定義
  • 表單驗(yàn)證器的初始化與自定義
  • 多語言支持的實(shí)現(xiàn)
  • 處理表單提交與錯誤返回
package main

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/locales/en"
	"github.com/go-playground/locales/zh"
	ut "github.com/go-playground/universal-translator"
	"github.com/go-playground/validator/v10"
	enTranslations "github.com/go-playground/validator/v10/translations/en"
	zhTranslations "github.com/go-playground/validator/v10/translations/zh"
)

// 定義一個全局翻譯器
var trans ut.Translator

表單數(shù)據(jù)結(jié)構(gòu)定義

首先,我們定義用戶提交的表單數(shù)據(jù)結(jié)構(gòu) SignUpParam。這個結(jié)構(gòu)體中包含了用戶注冊時(shí)所需的各個字段,并通過結(jié)構(gòu)標(biāo)簽(tags)指定了驗(yàn)證規(guī)則。

type SignUpParam struct {
	Age        uint8  `json:"age" binding:"gte=1,lte=130"`
	Name       string `json:"name" binding:"required"`
	Email      string `json:"email" binding:"required,email"`
	Password   string `json:"password" binding:"required"`
	RePassword string `json:"re_password" binding:"required,eqfield=Password"`
	Date       string `json:"date" binding:"required,datetime=2006-01-02,checkDate"`
}
  • Age 字段必須在 1 到 130 歲之間。
  • Name 字段不能為空。
  • Email 字段必須是有效的電子郵件地址。
  • PasswordRePassword 字段必須一致。
  • Date 字段需要使用自定義校驗(yàn)方法 checkDate,確保輸入日期晚于當(dāng)前日期。

初始化與自定義表單驗(yàn)證器

在 Gin 框架中,我們可以通過 binding.Validator.Engine() 獲取到內(nèi)置的驗(yàn)證器,并對其進(jìn)行自定義。

在下面的代碼中,我們完成了翻譯器的初始化,并注冊了自定義的標(biāo)簽名稱和驗(yàn)證方法。

func InitTrans(locale string) (err error) {
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {

		// 注冊獲取 JSON tag 的自定義方法
		v.RegisterTagNameFunc(func(fld reflect.StructField) string {
			name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
			if name == "-" {
				return ""
			}
			return name
		})

		// 注冊結(jié)構(gòu)體級別的驗(yàn)證函數(shù)
		v.RegisterStructValidation(SignUpParamStructLevelValidation, SignUpParam{})

		// 注冊自定義校驗(yàn)方法
		if err := v.RegisterValidation("checkDate", customFunc); err != nil {
			return err
		}

		// 初始化多語言支持
		zhT := zh.New() 
		enT := en.New()
		uni := ut.New(enT, zhT, enT)

                var ok bool
		trans, ok = uni.GetTranslator(locale)
		if !ok {
			return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
		}

		// 注冊語言翻譯
		switch locale {
		case "en":
			err = enTranslations.RegisterDefaultTranslations(v, trans)
		case "zh":
			err = zhTranslations.RegisterDefaultTranslations(v, trans)
		default:
			err = enTranslations.RegisterDefaultTranslations(v, trans)
		}
		if err != nil {
			return err
		}

		// 注冊自定義翻譯
		if err := v.RegisterTranslation(
			"checkDate",
			trans,
			registerTranslator("checkDate", "{0}必須晚于當(dāng)前日期"),
			translate,
		); err != nil {
			return err
		}
		return
	}
	return
}

實(shí)現(xiàn)自定義校驗(yàn)邏輯

在上面的代碼中,我們自定義了兩個校驗(yàn)函數(shù):

  • customFunc:用于校驗(yàn)日期是否晚于當(dāng)前日期。
  • SignUpParamStructLevelValidation:用于校驗(yàn)兩個密碼字段是否一致。
func customFunc(fl validator.FieldLevel) bool {
	date, err := time.Parse("2006-01-02", fl.Field().String())
	if err != nil {
		return false
	}
	return date.After(time.Now())
}

func SignUpParamStructLevelValidation(sl validator.StructLevel) {
	su := sl.Current().Interface().(SignUpParam)
	if su.Password != su.RePassword {
		sl.ReportError(su.RePassword, "re_password", "RePassword", "eqfield", "password")
	}
}

處理多語言錯誤提示

為了確保錯誤信息能夠根據(jù)用戶的語言偏好正確返回,我們注冊了一個自定義的翻譯函數(shù) registerTranslator,并在驗(yàn)證失敗時(shí)使用該函數(shù)對錯誤信息進(jìn)行翻譯。

// registerTranslator 為自定義字段添加翻譯功能
func registerTranslator(tag string, msg string) validator.RegisterTranslationsFunc {
	return func(trans ut.Translator) error {
		if err := trans.Add(tag, msg, false); err != nil {
			return err
		}
		return nil
	}
}

// translate 自定義字段的翻譯方法
func translate(trans ut.Translator, fe validator.FieldError) string {
	msg, err := trans.T(fe.Tag(), fe.Field())
	if err != nil {
		panic(fe.(error).Error())
	}
	return msg
}

主程序邏輯

最后,我們在 Gin 中處理用戶的注冊請求。當(dāng)用戶提交的數(shù)據(jù)驗(yàn)證失敗時(shí),系統(tǒng)會自動返回翻譯后的錯誤提示信息。

// removeTopStruct 去除字段名中的結(jié)構(gòu)體名稱標(biāo)識
// refer from:https://github.com/go-playground/validator/issues/633#issuecomment-654382345
func removeTopStruct(fields map[string]string) map[string]string {
	res := map[string]string{}
	for field, err := range fields {
		res[field[strings.Index(field, ".")+1:]] = err
	}
	return res
}

func main() {
	// 初始化翻譯器
	if err := InitTrans("zh"); err != nil {
		fmt.Printf("初始化翻譯器失敗: %v\n", err)
		return
	}

	r := gin.Default()

	r.POST("/signup", func(c *gin.Context) {
		var u SignUpParam
		if err := c.ShouldBind(&u); err != nil {
			errs, ok := err.(validator.ValidationErrors)
			if !ok {
				c.JSON(http.StatusOK, gin.H{"msg": err.Error()})
				return
			}
			c.JSON(http.StatusOK, gin.H{"msg": removeTopStruct(errs.Translate(trans))})
			return
		}

		// 其他的一些業(yè)務(wù)邏輯操作……

		c.JSON(http.StatusOK, gin.H{"msg": "success"})
	})

	err := r.Run(":8080")
	if err != nil {
		fmt.Printf("服務(wù)器運(yùn)行失敗: %v\n", err)
	}
}

總結(jié)

本文通過一個完整的示例,展示了如何在 Go 語言中使用 Gin 框架實(shí)現(xiàn)多語言的表單驗(yàn)證。

我們不僅探討了基礎(chǔ)的驗(yàn)證規(guī)則,還介紹了如何自定義驗(yàn)證邏輯以及如何實(shí)現(xiàn)國際化的錯誤提示。這種方式使得我們的應(yīng)用程序不僅在功能上更加強(qiáng)大,同時(shí)也能更好地適應(yīng)全球化的需求。

到此這篇關(guān)于Go語言結(jié)合validator包實(shí)現(xiàn)表單驗(yàn)證的文章就介紹到這了,更多相關(guān)Go validator表單驗(yàn)證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang?PHP?數(shù)據(jù)綁定示例分析

    Golang?PHP?數(shù)據(jù)綁定示例分析

    這篇文章主要為大家介紹了Golang?PHP?數(shù)據(jù)綁定示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 詳解如何利用Golang泛型提高編碼效率

    詳解如何利用Golang泛型提高編碼效率

    Golang的泛型已經(jīng)出來有一段時(shí)間了,大家應(yīng)該或多或少對它有所了解。雖然Golang的泛型在功能上確實(shí)比較簡單,而且確實(shí)可能會增加代碼的復(fù)雜度,過度使用可能還會降低代碼可讀性。本文就來介紹一下Golang泛型的相關(guān)知識吧
    2023-04-04
  • go-micro開發(fā)RPC服務(wù)以及運(yùn)行原理介紹

    go-micro開發(fā)RPC服務(wù)以及運(yùn)行原理介紹

    這篇文章介紹了go-micro開發(fā)RPC服務(wù)的方法及其運(yùn)行原理,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • gRPC的發(fā)布訂閱模式及REST接口和超時(shí)控制

    gRPC的發(fā)布訂閱模式及REST接口和超時(shí)控制

    這篇文章主要為大家介紹了gRPC的發(fā)布訂閱模式及REST接口和超時(shí)控制,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang程序?qū)觩rometheus過程

    golang程序?qū)觩rometheus過程

    文章介紹了如何在Golang項(xiàng)目中集成Prometheus進(jìn)行監(jiān)控,包括安裝客戶端庫、定義和注冊指標(biāo)、暴露指標(biāo)端點(diǎn)、更新指標(biāo)值、配置標(biāo)簽和注冊表,以及生產(chǎn)環(huán)境的建議配置
    2025-10-10
  • 一文帶你了解Go語言中鎖特性和實(shí)現(xiàn)

    一文帶你了解Go語言中鎖特性和實(shí)現(xiàn)

    Go語言中的sync包主要提供的對并發(fā)操作的支持,標(biāo)志性的工具有cond(條件變量)?once?(原子性)?還有?鎖,本文會主要向大家介紹Go語言中鎖的特性和實(shí)現(xiàn),感興趣的可以了解下
    2024-03-03
  • Go 自定義error錯誤的處理方法

    Go 自定義error錯誤的處理方法

    這篇文章主要介紹了Go 自定義error錯誤的處理方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Go表達(dá)式引擎expr基礎(chǔ)用法實(shí)戰(zhàn)指南

    Go表達(dá)式引擎expr基礎(chǔ)用法實(shí)戰(zhàn)指南

    expr是一個高性能的 Go 表達(dá)式引擎,它允許你在代碼中安全地執(zhí)行動態(tài)生成的表達(dá)式,本文給大家介紹Go表達(dá)式引擎expr基礎(chǔ)用法實(shí)戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • go語言多線程操作實(shí)現(xiàn)

    go語言多線程操作實(shí)現(xiàn)

    多線程是一種使程序能夠并行處理多個任務(wù)的技術(shù),Go語言通過goroutine和channel提供了一種相比傳統(tǒng)線程更輕量級、易于管理的并發(fā)實(shí)現(xiàn)方式,本文就來介紹一下go語言多線程操作實(shí)現(xiàn),感興趣的可以了解一下
    2024-11-11
  • 詳解如何使用Go語言進(jìn)行文件監(jiān)控和通知

    詳解如何使用Go語言進(jìn)行文件監(jiān)控和通知

    在Go語言中,文件監(jiān)控通常涉及到文件系統(tǒng)事件的監(jiān)聽,文件或目錄的狀態(tài)發(fā)生變化(如創(chuàng)建、刪除、修改等)時(shí),你的程序需要得到通知,所以本文給大家介紹了如何使用Go語言進(jìn)行文件監(jiān)控和通知,需要的朋友可以參考下
    2024-06-06

最新評論

衡东县| 泰宁县| 临潭县| 吉林市| 长武县| 泽库县| 遂平县| 霍城县| 定陶县| 册亨县| 新疆| 绍兴市| 阜城县| 宜良县| 黄大仙区| 美姑县| 兴安县| 卢湾区| 沙河市| 青冈县| 巧家县| 上杭县| 罗源县| 祁东县| 唐海县| 蚌埠市| 黄骅市| 旺苍县| 修文县| 新泰市| 定远县| 尉氏县| 新平| 山阴县| 宜兰市| 肥城市| 游戏| 若羌县| 城市| 嘉兴市| 宝应县|