簡體   English   中英

Spring - 永遠不會調用@Valid 的驗證

[英]Spring - Validation with @Valid is never called

試圖簡單地驗證我的 bean 的一個字段,而不是手動執行它想要檢查 Spring 驗證,但到目前為止沒有太多運氣。

簡而言之:

當我調用@RestController的方法時,似乎永遠不會調用@Valid注釋的驗證

我的代碼:

pom.xml (用於驗證部分)

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>

Spring 是 4.1.1 版

驗證器

package mypackage;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

public class UtenteValidator implements Validator{

    public UtenteValidator() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return UtenteLite.class.equals(clazz);
    }

//validation test
    @Override
    public void validate(Object target, Errors errors) {
        UtenteLite user = (UtenteLite) target;

          if(user.getName != "foo") {
              errors.rejectValue("name", "name not correct");
          }

    }




}

控制器

package myPackage;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/users")
public class UsersController {


    public UsersController() {

    }

//tried to put @InitBinder, but no luck
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new UtenteValidator());
    }

    @ResponseBody
    @RequestMapping(value="", method=RequestMethod.PUT)
    public <T> ResponseEntity<T> aggiornaUtente(@RequestBody @Valid UtenteLite utente, BindingResult result)
    {
        ResponseEntity<T> responseEntity=null;

        return responseEntity;
    }


}

BindingResult結果對象始終顯示零錯誤,並且從不調用validatesupportsinitBinder方法。

找到了這個教程,內容如下:

何時調用 @InitBinder 方法?

如果我們不指定此注釋的“值”元素,@InitBinder 注釋的方法將在每個 HTTP 請求上被調用。

WebDataBinder 參數特定於模型屬性。 這意味着每次 Spring 創建模型屬性時,都會使用 WebDataBinder 的新實例調用此方法。

所以我嘗試將我的控制器方法更改為添加@ModelAttribute ,現在調用驗證代碼但 requestBody 對象(“utente”對象)為空,因此驗證總是失敗,因為字段都是空值:

@ResponseBody
    @RequestMapping(value="", method=RequestMethod.PUT)
    public <T> ResponseEntity<T> aggiornaUtente(@RequestBody @Valid @ModelAttribute("utente") UtenteLite utente, BindingResult result)
    { 
...
}

utente方法參數使用 JSON 作為請求的正文傳遞。

好的,

經過多次嘗試,我僅通過在我的 pom.xml 中添加 hibernate-validation artifact 引用就成功地生成了一個有效的解決方案。

我錯誤地認為 hibernate-validator 是強制性的,只有當我在 bean 屬性上使用驗證注釋時(如@NotNull 、@Pattern 等)。

所以只有通過添加這個片段,我才能解決我的問題(希望這會為其他人節省幾個小時的工作):

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.3.Final</version>
</dependency>

現在完整的代碼是:

驗證器

package mypackage;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

public class UtenteValidator implements Validator{

    public UtenteValidator() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return UtenteLite.class.equals(clazz);
    }

//validation test
    @Override
    public void validate(Object target, Errors errors) {
        UtenteLite user = (UtenteLite) target;

          if(user.getName != "foo") {
              errors.rejectValue("name", "name not correct");
          }

    }




}

控制器

package myPackage;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/users")
public class UsersController {


    public UsersController() {

    }

//tried to put @InitBinder, but no luck
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new UtenteValidator());
    }

    @ResponseBody
    @RequestMapping(value="", method=RequestMethod.PUT)
    public <T> ResponseEntity<T> aggiornaUtente(@RequestBody @Valid UtenteLite utente)
    {
        ResponseEntity<T> responseEntity=null;

        return responseEntity;
    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM