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

dev*_*dar 4 java validation spring spring-mvc

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

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

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

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

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

班主任

   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;
Run Code Online (Sandbox Code Playgroud)

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");
            }
..............
}
Run Code Online (Sandbox Code Playgroud)

调节器

@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();

}
Run Code Online (Sandbox Code Playgroud)

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

 @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();

}
Run Code Online (Sandbox Code Playgroud)

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

Sot*_*lis 7

您无需在中注册验证器WebDataBinder.相反,您可以创建两个(或任何数字)不同的Validator为每个需求类.例如

public class OfficerRegistrationValidation implements Validator {...}

public class OfficerUpdateValidation implements Validator {...}
Run Code Online (Sandbox Code Playgroud)

使用@Component<bean>声明为每个bean创建bean .在@Controller课堂上注入它们

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

    @Inject
    private OfficerUpdateValidation officerUpdateValidation;
Run Code Online (Sandbox Code Playgroud)

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

@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
}
Run Code Online (Sandbox Code Playgroud)

不要注册其中任何一个WebDataBinder.@Valid将执行默认验证,例如,for @NotEmpty@Patternannotations.您的Validator实例将针对特定用例执行自定义验证.