如何从Spring MVC中的控制器中分离验证器

时间:2013-12-30 13:40:42

标签: java spring spring-mvc testing

我已经根据我在Spring Petclinic示例应用程序中找到的内容,为我的Web应用程序构建了带有验证程序的Spring MVC(3.2 / 4.0)控制器。但是,在示例应用程序中,使用new关键字在相关控制器内创建验证器,从而创建紧密耦合。既然我正在编写测试来覆盖这段代码,那么由于这种耦合,很难将这些类隔离开来。

是否建议将验证器与控制器分离?这个问题还有其他解决办法吗?

以下是紧凑型耦合的Petclinic应用中的一个例子:

@RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
    new PetValidator().validate(pet, result);
    if (result.hasErrors()) {
        return "pets/createOrUpdatePetForm";
    } else {
        this.clinicService.savePet(pet);
        status.setComplete();
        return "redirect:/owners/{ownerId}";
    }
}

3 个答案:

答案 0 :(得分:1)

在您的应用程序上下文中将Petvalidator定义为bean,并对您的控制器进行以下更改

@RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
    PetValidator petValidator;   //change this line
    petValidator.validate(pet,result);  //change this line

    if (result.hasErrors()) {
        return "pets/createOrUpdatePetForm";
    } else {
        this.clinicService.savePet(pet);
        status.setComplete();
        return "redirect:/owners/{ownerId}";
    }
}

您可以使用属性注入将适当的Petvalidator注入控制器。如果您使用组件扫描添加以下内容,则将已注册的bean自动装入您的控制器。

@Autowired
PetValidator petValidator;

在您的控制器内部,而不是PetValidator petvalidator;

答案 1 :(得分:0)

这就是@Valid的用途:

public String processCreationForm(@ModelAttribute("pet") @Valid Pet pet, BindingResult result, SessionStatus status) {
  if (result.hasErrors()) {

您无需亲自进行验证。让Spring自动处理它。

答案 2 :(得分:0)

如果您的PetValidator类型为org.springframework.validation.Validator,则可以使用WebDataBinder.setValidator()绑定它。

在你的控制器或@ControllerAdvice中添加一个用@InitBinder注释的方法。

@InitBinder
public void initBinder(WebDataBinder binder) {
    // Add the validator. Could be an auto wired instance as well.
    binder.setValidator(new PetValidator());
}

现在,验证器支持的所有类型的对象都将自动验证。