SpringMvc如何根据用户正在执行的函数为Object使用不同的validation器

我有一个名为“人员”的对象我希望根据用户想要执行的function执行不同类型的validation,例如,当正在注册/保存人员记录时,我想要检查其是否为NULL并生成一名官员数字以及更新记录时我不想执行此检查并执行更新语句。

但是,从那以后我就遇到了问题。 我看过不同的方法,它不够干净或灵活。 我尝试过以下方法,面临的问题是:

  1. 将注册validation器与Controller一起使用但每个Controller仅允许注册一个validation器。 这使得该validation的实现适用于控制器中执行的所有function。

    1. 使用Validator Facade可以为整个应用程序提供一个validation类,但是它会根据对象的实例类型选择validation,这会将每个对象的validation器数量限制为一个(需要更正)。

如何在不为该方法使用单独的Controller的情况下为同一对象执行不同的validation。

class主任

public class Officers implements Serializable{ private String userName; private String password; private String password2; private String fName; private String lName; private String oName; private int divisionNo; private officerNumber; 

OfficerRegistrationValidation类

  @Component public class OfficerRegistrationValidation implements Validator { public boolean supports(Class clazz) { return Officers.class.equals(clazz); } public void validate(Object target, Errors errors) { Officers officer = (Officers) target; if (officer.getPassword() == null) { errors.rejectValue("password", "password.required"); } if (officer.getPassword2() == null) { errors.rejectValue("password2", "password2.required"); } .............. } 

调节器

 @Controller public class OfficerController { @InitBinder("officers") protected void initBinder(WebDataBinder binder){ //removes white spaces binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); //formats date SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); //By passing true this will convert empty strings to null binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); dateFormat.setLenient(false); //binder.setValidator(new OfficerRegistrationValidation()); binder.setValidator(officerRegistrationValidation); } @RequestMapping(value="officer_registration_save.htm", method = RequestMethod.POST) public ModelAndView loadPage(HttpServletRequest request,HttpServletResponse response, @ModelAttribute Officers officer,BindingResult result,ModelMap m, Model model) throws Exception { if(result.hasErrors()){ return new ModelAndView("officer_registration"); }else doSave(); } 

需要使用不同类型的validation来更新记录

  @RequestMapping(value="officer_registration_update.htm", method = RequestMethod.POST) public ModelAndView loadPage(HttpServletRequest request,HttpServletResponse response, @ModelAttribute Officers officer,BindingResult result,ModelMap m, Model model) throws Exception { if(result.hasErrors()){ return new ModelAndView("officer_registration"); }else doSave(); } 

我最终使用的方法是通过HttpServletRequest更新或保存按钮值,并在validation器中包含该值以决定是否validation更新或保存。 在我寻找最干净,最好的方法之前,有没有人做过类似的事情。 到目前为止我已经决定使用HttpServletRequest请求request.getParameter(“action”); 我发现这种方法有点陈旧而且不干净。

您无需在WebDataBinder注册validation器。 相反,您可以为每个需求创建两个(或任意数量)不同的Validator类。 例如

 public class OfficerRegistrationValidation implements Validator {...} public class OfficerUpdateValidation implements Validator {...} 

使用@Component声明为每个bean创建bean。 在@Controller类中注入它们

 @Controller public class OfficerController { @Inject private OfficerRegistrationValidation officerRegistrationValidation; @Inject private OfficerUpdateValidation officerUpdateValidation; 

然后在每种方法中使用您需要的特定组件

 @RequestMapping(method = RequestMethod.POST) public /* or other return type */ String registerOfficer(@Valid @ModelAttribute Officer officer, BindingResult errors /*, more parameters */) { officerRegistrationValidation.validate(officer, errors); if (errors.hasErrors()) { ...// do something } ...// return something } 

不要在WebDataBinder注册其中任何一个。 @Valid将执行默认validation,例如@NotEmpty@Pattern注释。 您的Validator实例将针对特定用例执行自定义validation。