2016-03-11 69 views
1

我正在嘗試構建一個小的POC來檢查我們是否可以在我們的項目(REST端點)上使用Spring驗證。目標是在某些組件的方法上使用@Valid註釋,使用JSR-303註釋爲參數進行註釋,併爲自定義驗證邏輯構建一些Validator實例。在Spring組件方法上使用@Valid註解

考慮以下情形:

帳戶(getter和setter中省略)

public class Account { 
    private int id; 

    @Min(0) private double amount; 

    @NonNull private String cardholder; 
} 

的AccountController

@RestController 
@RequestMapping("/account") 
public class AccountController {  
    @Autowired private AccountService service; 

    @RequestMapping(method= RequestMethod.POST) 
    public void post(@RequestBody Account account) { 
     service.save(account); 
    } 
} 

帳戶服務

@Component 
public class AccountService { 
    public void save(**@Valid** Account account) { 
     // Logic ommited 
     log.info("Account saved!"); 
    } 
} 

AccountSaveValidator

public class AccountSaveValidator implements Validator { 
    @Override 
    public boolean supports(Class<?> clazz) { return Account.class.isAssignableFrom(clazz); } 

    @Override 
    public void validate(Object target, Errors errors) { 
     Account account = (Account) target; 

     if (**if account does not exist**) 
      errors.rejectValue("id", "account.not-exists"); 
    } 
} 

每當我POST/account,所提到的驗證不運行,也不管是顯示Account saved!消息。但是,如果我將@Valid註釋放在AccountControllerPOST處理程序上,則會執行驗證。

我只能通過調用它像這樣保存()方法僅執行自定義驗證(AccountSaveValidator)手動:

ValidationUtils.invokeValidator(new AccountSaveValidator(), account, errors); 

if (errors.hasErrors()) { 
    throw new ValidationException(errors); 
} 

缺少什麼我在這裏?我讀過這些驗證組件通常與Spring-MVC一起使用,但它可以在沒有它的情況下使用。

的gradle這個依賴我有如下:

compile "org.springframework:spring-core" 
compile "org.springframework:spring-context" 
compile "org.springframework:spring-web" 
compile "org.springframework.boot:spring-boot" 
compile "org.springframework.boot:spring-boot-starter-web" 
compile "org.springframework.boot:spring-boot-autoconfigure" 

compile "javax.validation:validation-api:1.1.0.Final" 
compile "org.hibernate:hibernate-validator:5.2.4.Final" 

回答

1

一對夫婦的事情,我相信你對這裏的問題頭銜是什麼,你實際上是問在這裏有點misrepresentitive。你並沒有試圖驗證一個spring組件。你希望在Spring組件中進行方法參數驗證,這是不同的。我相信你在這裏的問題是這個問題的重複:JSR 303. Validate method parameter and throw exception。有一些例子說明如何使用代理和MethodValidationInterceptor來做你想做的事情。

我會在這裏添加一些額外的信息,試圖澄清JSR-303驗證的工作原理和原因。

  1. Spring MVC的參數:參數傳遞到Spring MVC的組件使用的用戶自定義和默認HandlerParameterResolver個組合解決。 Spring的默認MVC配置的一部分包括通過@RequestParam@PathVariable自動映射到原始類型的鉤子,並且@RequestBody通過前面提到的HandlerParameterResolver映射到對象。與在Spring中自動配置這些HandlerParameterResolvers的方式一樣(主要是默認情況下),還有一些Validator被註冊到DataBinders中,它將請求中的數據映射到上面的參數,JSR-303驗證自動配置爲綁定到這些鉤子。這當然是對幕後發生的事情的簡單總結。

  2. Spring組件/豆:Spring Bean和組件通過Spring Bean驗證器驗證。你可以找到關於這個細節在這裏:在名爲「7.8.2配置Bean驗證實現」

+0

謝謝你的提示一節所述http://docs.spring.io/autorepo/docs/spring/3.2.x/spring-framework-reference/html/validation.html,我已經更新了標題,以反映實際的意圖。 – everton