我已经根据我在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}";
}
}
答案 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());
}
现在,验证器支持的所有类型的对象都将自动验证。