2016-03-11 71 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