在go-playground/validator中实现多语言翻译支持时,需要正确配置翻译器并确保验证错误使用对应的翻译器。根据你的代码片段,问题可能出现在翻译器的注册或使用方式上。
以下是完整的多语言翻译实现示例:
package main
import (
"fmt"
"net/http"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/it"
"github.com/go-playground/locales/fr"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
enTranslations "github.com/go-playground/validator/v10/translations/en"
itTranslations "github.com/go-playground/validator/v10/translations/it"
frTranslations "github.com/go-playground/validator/v10/translations/fr"
)
var (
uni *ut.UniversalTranslator
validate *validator.Validate
)
func init() {
// 初始化本地化实例
enLocale := en.New()
itLocale := it.New()
frLocale := fr.New()
// 创建通用翻译器,第一个参数是备用语言
uni = ut.New(enLocale, enLocale, itLocale, frLocale)
// 创建验证器实例
validate = validator.New()
// 注册各种语言的翻译
registerTranslations("en")
registerTranslations("it")
registerTranslations("fr")
}
func registerTranslations(lang string) {
if trans, found := uni.GetTranslator(lang); found {
switch lang {
case "en":
enTranslations.RegisterDefaultTranslations(validate, trans)
case "it":
itTranslations.RegisterDefaultTranslations(validate, trans)
case "fr":
frTranslations.RegisterDefaultTranslations(validate, trans)
}
}
}
type User struct {
Name string `validate:"required,min=3"`
Email string `validate:"required,email"`
Age int `validate:"gte=18"`
}
func validateUser(user User, lang string) []string {
// 获取对应语言的翻译器
trans, _ := uni.GetTranslator(lang)
// 执行验证
err := validate.Struct(user)
if err != nil {
var errors []string
if validationErrors, ok := err.(validator.ValidationErrors); ok {
// 使用正确的翻译器翻译错误
translatedErrors := validationErrors.Translate(trans)
for _, errMsg := range translatedErrors {
errors = append(errors, errMsg)
}
}
return errors
}
return nil
}
func handler(w http.ResponseWriter, r *http.Request) {
// 从Accept-Language头部获取语言
acceptLanguage := r.Header.Get("Accept-Language")
// 简化处理:取前两个字符作为语言代码
lang := "en" // 默认语言
if len(acceptLanguage) >= 2 {
lang = acceptLanguage[:2]
}
user := User{
Name: "Jo", // 故意设置短名称触发错误
Email: "invalid-email",
Age: 16,
}
errors := validateUser(user, lang)
if errors != nil {
fmt.Fprintf(w, "Validation errors (%s):\n", lang)
for _, err := range errors {
fmt.Fprintf(w, "- %s\n", err)
}
} else {
fmt.Fprintf(w, "Validation passed")
}
}
func main() {
http.HandleFunc("/validate", handler)
http.ListenAndServe(":8080", nil)
}
关键点说明:
- 翻译器注册:确保每种语言都正确注册了默认翻译:
// 每种语言都需要单独注册
registerTranslations("en")
registerTranslations("it")
registerTranslations("fr")
- 验证时使用对应翻译器:在验证函数中获取正确的翻译器:
func validateUser(user User, lang string) []string {
trans, _ := uni.GetTranslator(lang) // 获取对应语言的翻译器
// ...
translatedErrors := validationErrors.Translate(trans) // 使用该翻译器
}
- HTTP头部处理示例:
acceptLanguage := r.Header.Get("Accept-Language")
lang := "en" // 默认值
if len(acceptLanguage) >= 2 {
lang = acceptLanguage[:2]
}
测试不同语言的验证错误输出:
# 英语
curl -H "Accept-Language: en" http://localhost:8080/validate
# 意大利语
curl -H "Accept-Language: it" http://localhost:8080/validate
# 法语
curl -H "Accept-Language: fr" http://localhost:8080/validate
如果问题仍然存在,检查验证器实例是否全局唯一,确保在验证时使用的是同一个validate实例,该实例已经注册了所有语言的翻译。