Since springmvc 3.x now supports jsr303 and old spring style validator, i want to mix them in my sample apps. But there is only one method enabled for a specified controller, is that the limit of spring framework or JSR standard?
Here is my sample code.
User.java, stands for the domain model, uses JSR303 for validation.
public class User{
@Size(max = 16, message = "user loginId max-length is 16")
private String loginId;
//omit getter and setter
}
UserValidator.java, implements the org.springframework.validation.Validator
interface to support user validation.
public class UserValidator implements Validator {
private UserService userService;
public boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
User u = (User) target;
// loginName check for new user
if (u.getUserId() == null && !userService.isLoginIdUnique(u.getLoginId(), null)) {
errors.rejectValue("loginId", "user.loginId.unique", new Object[] { u.getLoginId() }, null);
}
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
UserController.java, uses InitBinder
annotation to inject UserValidator
into WebDataBinder
.
@Controller("jspUserController")
@RequestMapping("/sys/users")
public class UserController {
private UserValidator userValidator;
@Autowired
public void setUserValidator(UserValidator userValidator) {
this.userValidator = userValidator;
}
/*@InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
binder.setValidator(userValidator);
}*/
@RequestMapping(value = "/save")
public String save(@Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) {
if (bindingResult.hasErrors()) {
return "/sys/user/edit";
}
userService.saveUser(user);
return "redirect:/sys/users/index";
}
}
If I uncomment the @InitBinder("user")
in UserController, the JSR303 validation will be disabled. While the current commented code will use JSR validator to do the validation.
Can anyone give me a workaround to mix them in one controller?
You can ADD your validator instead of SETTING it :
@InitBinder("user")
public void initBinderUser(WebDataBinder binder) {
binder.addValidators(userValidator);
}
This will execute the JSR303 validations first and then your custom validator. No need then to call the validator directly in the save method.
You can use your validator directly and let the global LocalValidatorFactoryBean (JSR-303) do its work as well:
@Controller("jspUserController")
@RequestMapping("/sys/users")
public class UserController {
private UserValidator userValidator;
@Autowired
public void setUserValidator(UserValidator userValidator) {
this.userValidator = userValidator;
}
@RequestMapping(value = "/save")
public String save(@Valid User user, BindingResult bindingResult, Model model, HttpServletRequest request) {
this.userValidator.validate(user, bindingResult);
if (bindingResult.hasErrors()) {
return "/sys/user/edit";
}
userService.saveUser(user);
return "redirect:/sys/users/index";
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With