当前位置: 首页 > article >正文

【Validator】universal-translator,实现动态多语言切换,go案例根据Accept-Language 动态设置 locale

代码实现

根据 locale 设置动态语言翻译,具体包括初始化翻译器、注册多语言翻译规则、动态选择语言、以及输出本地化错误提示。

package validate

import (
	"errors"
	"fmt"

	"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 validate = validator.New()
var uni *ut.UniversalTranslator

func LocalizedValidation() {
	// 初始化支持语言
	en := en.New()
	zh := zh.New()
	uni = ut.New(en, zh) // 初始化翻译器支持中英文
	locale := "zh"       // 动态设置语言,可从配置或用户选择中获取

	// 根据 locale 获取翻译器
	trans, _ := uni.GetTranslator(locale)
	switch locale {
	case "en":
		enTranslations.RegisterDefaultTranslations(validate, trans)
	case "zh":
		zhTranslations.RegisterDefaultTranslations(validate, trans)
	default:
		fmt.Println("Unsupported locale, defaulting to English")
		enTranslations.RegisterDefaultTranslations(validate, trans)
	}

	// 定义需要验证的结构体
	type User struct {
		Name  string `validate:"required"`     // 必填字段
		Email string `validate:"required,email"` // 必填且必须是邮箱格式
	}
	user := User{}

	// 验证结构体
	err := validate.Struct(user)
	if err != nil {
		var validationErrors validator.ValidationErrors
		if errors.As(err, &validationErrors) {
			for _, e := range validationErrors {
				// 输出本地化的错误提示信息
				fmt.Println(e.Translate(trans))
			}
		}
	}
}

核心功能点

功能模块关键代码/方法描述
初始化翻译器ut.New(en, zh)支持多种语言的翻译器初始化。
动态语言选择uni.GetTranslator(locale)根据用户 locale 设置动态语言翻译。
注册翻译规则enTranslations.RegisterDefaultTranslations为不同语言注册默认验证规则翻译。
捕获验证错误validator.ValidationErrors验证失败时,捕获错误信息。
本地化错误输出FieldError.Translate(trans)将错误翻译为用户指定语言的提示信息。

运行效果示例

  • 输入

    User{
        Name:  "",
        Email: "invalid-email",
    }
    
  • 输出locale = "zh"

    Name 为必填字段
    Email 必须是一个有效的邮箱地址
    
  • 输出locale = "en"

    Name is a required field
    Email must be a valid email address
    

根据Accept-Language 动态设置 locale

package main

import (
	"errors"
	"fmt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"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 validate = validator.New()
var uni *ut.UniversalTranslator

// 初始化翻译器支持的语言
func initTranslator() {
	en := en.New()
	zh := zh.New()
	uni = ut.New(en, zh)
}

// 动态获取 locale 并设置翻译器
func getTranslator(c *gin.Context) ut.Translator {
	// 获取请求头的 Accept-Language
	lang := c.GetHeader("Accept-Language")
	if lang == "" {
		lang = "en" // 默认语言
	}

	// 提取主语言部分(如 zh-CN 取 zh)
	lang = strings.Split(lang, ",")[0]
	lang = strings.Split(lang, "-")[0]

	// 获取对应的 Translator
	trans, _ := uni.GetTranslator(lang)
	switch lang {
	case "en":
		enTranslations.RegisterDefaultTranslations(validate, trans)
	case "zh":
		zhTranslations.RegisterDefaultTranslations(validate, trans)
	default:
		// 如果不支持该语言,默认使用英文
		trans, _ = uni.GetTranslator("en")
		enTranslations.RegisterDefaultTranslations(validate, trans)
	}
	return trans
}

// 定义需要验证的结构体
type User struct {
	Name  string `validate:"required"`
	Email string `validate:"required,email"`
}

func main() {
	initTranslator()

	r := gin.Default()

	r.POST("/validate", func(c *gin.Context) {
		// 动态获取翻译器
		trans := getTranslator(c)

		// 从请求体解析用户数据
		var user User
		if err := c.ShouldBindJSON(&user); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"})
			return
		}

		// 验证结构体
		err := validate.Struct(user)
		if err != nil {
			var validationErrors validator.ValidationErrors
			if errors.As(err, &validationErrors) {
				// 收集本地化错误信息
				errorMessages := make([]string, len(validationErrors))
				for i, e := range validationErrors {
					errorMessages[i] = e.Translate(trans)
				}
				c.JSON(http.StatusBadRequest, gin.H{"errors": errorMessages})
				return
			}
		}

		// 验证成功
		c.JSON(http.StatusOK, gin.H{"message": "Validation passed!"})
	})

	// 启动服务
	r.Run(":8080")
}


核心步骤
  1. 初始化翻译器
  • 使用 ut.New() 初始化支持的语言翻译器(如英文 en 和中文 zh)。
  1. 从请求头获取 Accept-Language
  • 提取用户请求中的 Accept-Language,如 zh-CNen-US,并解析主语言部分(zhen)。
  1. 动态注册翻译规则
  • 根据解析出的语言动态注册相应的翻译规则(enTranslationszhTranslations)。
  1. 结构体验证
  • 使用 validator 验证用户提交的数据,捕获验证错误。
  1. 本地化错误输出
  • 将验证错误信息翻译为用户选择的语言,并返回给前端。

测试效果

请求 1:语言为中文
  • 请求头
  Accept-Language: zh-CN
  • 请求体
  {
    "Name": "",
    "Email": "invalid-email"
  }
  • 响应
  {
    "errors": [
      "Name 为必填字段",
      "Email 必须是一个有效的邮箱地址"
    ]
  }
请求 2:语言为英文
  • 请求头
  Accept-Language: en-US
  • 请求体
  {
    "Name": "",
    "Email": "invalid-email"
  }
  • 响应
  {
    "errors": [
      "Name is a required field",
      "Email must be a valid email address"
    ]
  }
请求 3:语言为空(默认英文)
  • 请求头
  Accept-Language: 
  • 请求体
  {
    "Name": "",
    "Email": "invalid-email"
  }
  • 响应
  {
    "errors": [
      "Name is a required field",
      "Email must be a valid email address"
    ]
  }

https://github.com/0voice


http://www.kler.cn/a/524161.html

相关文章:

  • Charles 4.6.7 浏览器网络调试指南:流量过滤与分析(六)
  • openeuler 22.03 lts sp4 使用 cri-o 和 静态 pod 的方式部署 k8s-v1.32.0 高可用集群
  • 获取snmp oid的小方法1(随手记)
  • go gin配置air
  • 【JavaEE】_MVC架构与三层架构
  • k8s支持自定义field-selector spec.hostNetwork过滤
  • 论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(六)(完结)
  • 基于SpringBoot的中老年人文化活动管理系统
  • 图论——单源最短路的扩展应用
  • 【漫话机器学习系列】064.梯度下降小口诀(Gradient Descent rule of thume)
  • RAG技术:通过向量检索增强模型理解与生成能力
  • C语言编程题思路汇总(字符串,数组相关)
  • GPU上没程序在跑但是显存被占用
  • [Java]快速入门
  • 2024年MR应用深度解析:Meta商店中的游戏与非游戏应用
  • 自主shell命令行解释器
  • HSM能为区块链、IoT等新兴技术提供怎样的保护?
  • fps一些内容添加
  • 构建 QA 系统:基于文档和模型的问答
  • [CISCN2019 华东南赛区]Web41
  • CTF-web: phar反序列化+数据库伪造 [DASCTF2024最后一战 strange_php]
  • 计算机毕业设计PySpark+hive招聘推荐系统 职位用户画像推荐系统 招聘数据分析 招聘爬虫 数据仓库 Django Vue.js Hadoop
  • 解决 Postman 报错一直转圈打不开
  • 2024年度技术总结——MCU与MEMS和TOF应用实践
  • Qt监控系统辅屏预览/可以同时打开4个屏幕预览/支持5x64通道预览/onvif和rtsp接入/性能好
  • 双层Git管理项目,github托管显示正常