Golang中Validator与Echo框架的字段验证问题

Golang中Validator与Echo框架的字段验证问题 大家好,我是 Echo 和验证器的新手。问题是,无论我如何发送 curl 请求,验证器似乎都不会触发,例如:

curl -X POST localhost:3000/user

这不应该返回一个空的用户对象,因为显然没有满足 min=5 的条件。

以下是我的演示代码:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/go-playground/validator/v10"
	"github.com/labstack/echo/v4"
)

type User struct {
	Email string `json:"email" form:"email" validate:"required,email"`
	Name  string `json:"name"               validate:"required,min=5"`
}

func (u User) String() string {
	return fmt.Sprintf("Name: %s | Email: %s", u.Name, u.Email)
}

type ResponseError struct {
	Message string `json:"message"`
}

type Validator struct {
	validator *validator.Validate
}

func (v *Validator) Validate(i interface{}) error {
	err := v.validator.Struct(i)
	if err != nil {
		return nil
	}
	return nil
}

func main() {

	e := echo.New()
	e.Validator = &Validator{validator: validator.New()}

	e.POST("/user", func(c echo.Context) error {
		var user User

		if err := c.Bind(&user); err != nil {
			return c.JSON(http.StatusBadRequest, ResponseError{Message: err.Error()})
		}
		log.Println(user)

		if err := c.Validate(&user); err != nil {
			return c.JSON(http.StatusBadRequest, ResponseError{Message: err.Error()})
		}
		return c.JSON(http.StatusOK, user)

	})

	e.Logger.Fatal(e.Start(":3000"))

}

我是不是误解了 validator.Struct() 的作用?

谢谢!


更多关于Golang中Validator与Echo框架的字段验证问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

当出现错误时,你仍然返回 nil,这就是根本原因。 你可以直接: return v.validator.Struct(i) 像这样

func (v *Validator) Validate(i interface{}) error {
	return v.validator.Struct(i)
}

更多关于Golang中Validator与Echo框架的字段验证问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在你的代码中,Validator.Validate 方法存在逻辑错误。当验证失败时,你返回了 nil,这导致验证错误被忽略。以下是修正后的代码:

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/go-playground/validator/v10"
    "github.com/labstack/echo/v4"
)

type User struct {
    Email string `json:"email" form:"email" validate:"required,email"`
    Name  string `json:"name"               validate:"required,min=5"`
}

func (u User) String() string {
    return fmt.Sprintf("Name: %s | Email: %s", u.Name, u.Email)
}

type ResponseError struct {
    Message string `json:"message"`
}

type CustomValidator struct {
    validator *validator.Validate
}

func (cv *CustomValidator) Validate(i interface{}) error {
    if err := cv.validator.Struct(i); err != nil {
        return err // 关键修改:返回验证错误
    }
    return nil
}

func main() {
    e := echo.New()
    e.Validator = &CustomValidator{validator: validator.New()}

    e.POST("/user", func(c echo.Context) error {
        var user User

        if err := c.Bind(&user); err != nil {
            return c.JSON(http.StatusBadRequest, ResponseError{Message: err.Error()})
        }
        log.Println(user)

        if err := c.Validate(&user); err != nil {
            return c.JSON(http.StatusBadRequest, ResponseError{Message: err.Error()})
        }
        return c.JSON(http.StatusOK, user)
    })

    e.Logger.Fatal(e.Start(":3000"))
}

关键修改在 CustomValidator.Validate 方法中:

  • 原代码在验证失败时返回 nil,导致错误被忽略
  • 修正后直接返回 validator.Struct() 的错误

测试验证失败的请求:

curl -X POST http://localhost:3000/user \
  -H "Content-Type: application/json" \
  -d '{"name":"abc","email":"invalid"}'

这会返回:

{
  "message": "Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag\nKey: 'User.Name' Error:Field validation for 'Name' failed on the 'min' tag"
}

验证成功的请求:

curl -X POST http://localhost:3000/user \
  -H "Content-Type: application/json" \
  -d '{"name":"validname","email":"test@example.com"}'

这会返回正确的用户对象。

回到顶部