SpringMvc How to use different validators for an object based on the function that the user pre-generates

I have an object called officers. I would like to pre-test various types of validation based on the function that the user wants to transform, for example, when registering or saving an officer’s record, I would like to read the check if it is NULL and generate the officer’s number, and when the record is updated, I would not want to preform this check and follow the update instruction.

However, I am having problems with this. I have looked at different approaches and it is not clean or flexible enough. I tried the following approaches and problems:

  • Using a registered validator with a controller, however, each controller allows only one validator to be registered. This makes the implementation of this check applicable to all functions previously generated in the controller.

    • Using the indicator validator may allow one verification class for the entire application, however, it selects verification based on the instance type for objects, and this limits the number of validators per object to one (to be fixed).

How can a preliminary check be performed for the same object without using a separate controller for this method.

Class staff

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 Class

  @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

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

You must use a different type of check for the updated record.

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

The approach that I ultimately used was to get the value of the button either updated or saved through the HttpServletRequest and included this in the validator to decide whether to check for updates or saving. Someone did something like this before I look for his cleanest and best approach. So far I have decided to use the HttpServletRequest request.getParameter ("action") request; I find this approach a bit old and not clean.

+4
source share
1 answer

You do not need to register validators in WebDataBinder . Instead, you can create two (or any number) of different Validator classes for each of your requirements. for instance

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

Create beans for each of them, either using the @Component declaration or <bean> . Add them to the @Controller class

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

Then use the ones you need in each of your methods.

 @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 } 

Do not register any of them with WebDataBinder . @Valid will perform a default check, for example for @NotEmpty or @Pattern . Your Validator instances will perform spot checks for a specific use case.

+7
source

Source: https://habr.com/ru/post/1482072/


All Articles